ES6学习笔记(1,let和const)
在介绍let和const之前我们先复习一下相关的知识点。
关于函数作用域
开发过程中,在ES6(ECMA2015)标准推出之前,声明变量的方式一直都是var,而变量的作用域一般也只在函数内部,即函数作用域。
function a () {
var test = 1;
}
console.log(test); //error, test is not defined
上面的实例反应了当我们定义在函数a中定义变量test的时候,其作用域只在a函数中,在函数a外面访问test,则会抛错。
关于变量提升
在javascript中,使用var声明的变量,不论是在什么地方声明的,都会提升到当前作用域的最顶部进行初始化,这种行为叫做变量提升
function test() {
console.log('1:', a); //undefined
if (false) {
var a = 1;
}
console.log('2:', a); //undefined
}
test();
关于上面的代码,两次访问a都是undefined,说明在作用域中实际上是能访问到a的,只不过未赋值,即使判断语句是false,第一个日志访问的a也不是is not defined,出现这种情况的原因实际上就是因为变量提升。
把上面的代码翻译成浏览器真正执行的代码实际上是:
function test() {
// 变量提升,对a进行初始化,但未赋值
var a;
console.log('1:', a); //undefined
if (false) {
a = 1;
}
console.log('2:', a); //undefined
}
由于变量提升的关系,因此在es6标准推出之前,javascript中实际上只有函数作用域,而没有块作用域({}),这里的块作用域可以简单的看做用{}包起来的代码。
let
let和const都能够声明块作用域,用法和var是类似的,特别都不会进行变量提升,而是被锁在当前的代码块中。
function test() {
if (true) {
console.log(a); // TDZ,俗称临时死区,用来描述变量不提升的现象
let a = 1;
}
}
test(); // a is not defined
function test() {
if (true) {
let a = 1;
}
console.log(a);
}
test(); // a is not defined
上面的两个例子都用let进行变量声明,第一个例子反映出来let声明的变量是不会出现变量提升现象的,而第二个例子说明let声明的变量只在块作用域中生效,那么正确的使用方法应该是:在块作用域中,先声明,在访问
function test() {
if (true) {
let a = 1;
console.log(a);
}
}
test() // a
const
const和let类似,用来声明常量,不过和let的区别则是,一旦声明则不可以更改,而且必须进行初始化赋值。下面的例子很清楚来说明这一点。
const type = 'aaa';
type = 'bbb';
console.log(type); // "type" is read-only
const type;
type = 'aaa';
console.log(type); // Missing initializer in const declaration
我们再来看看下面这个例子
const type = 'aaa';
let type = 'bbb';
console.log(type); // Identifier 'type' has already been declared
同样出现的报错,实际上我们不论是使用const 还是 let都不能这样重复声明相同名称的变量,但是使用var是可以的,原因可以简单的理解为因为变量提升的存在,导致声明只有一次,赋值有两次。
const最重要的特点是一点声明,不可以修改,但是假如定义的是对象Object,那么可以修改对象内部的属性值,原因是因为当我们修改对象内部的属性值的时候对象的内存地址实际上是没有变化的,但是假如我们直接修改对象本身,则会出现报错,在这种情况下需要使用let。
const type = {
a: 1,
}
type.a = 2 //没有直接修改type值,对象的指针不变,只是修改了type.a的属性值,这是允许的。
console.log(type) // {a: 2}
type = { // 直接修改type本身,对象的内存地址会发生变化,不允许。
a: 2,
}
console.log(type) // Identifier 'type' has already been declared
const 和 let 的异同点。
相同点:
- const和let都只在当前的块作用域内有效
- 不存在变量提升
- 不能重复声明
不同点: - const不能再赋值,let可以再赋值
临时死区(TDZ)
上面我们已经提到了TDZ的场景,那么,有什么用呢?答案就是没什么用。可以理解为一个便于说明的定义。
临时死区的意思是在当前作用域的块内,在声明变量前的区域叫做临时死区。
if (true) {
// 这块区域是TDZ
let a = 1;
}
块级作用域的使用场景
块级作用域有哪些使用场景呢?
在for循环中使用var声明的循环变量,会跳出循环污染当前的函数作用域
for (var i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i); // 5, 5, 5, 5, 5
}, 0);
}
console.log(i) // 5, i跳出了循环污染当前函数作用域
for (let i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i); // 0, 1, 2, 3, 4
}, 0);
}
console.log(i) // i is not defined i无法污染外部函数
全局作用于声明
如果在全局作用域使用let或者const声明,那么声明的变量本身就是全局变量,并不会挂在window下
let a = 1;
var b = 2;
console.log(a); // 1
console.log(window.a) // undefined
console.log(b); // 2
console.log(window.b) // 2
实践
在实际开发中,我们是使用var, let, 还是const取决于变量是否需要更新,不更新的变量用const,更新的变量用let。var能用的场景都可以使用let来替代,但是需要注意作用域的区别。
ES6学习笔记(1,let和const)的更多相关文章
- ES6学习笔记(一)——let和const
1.ES6学习之let.const (1).var.let.const 变(常)量声明 ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景. 在ES6中let就诞生了,实际上它 ...
- es6学习笔记1 --let以及const
let语句的基本用法: 1.let声明的变量为块级作用域,只在最近的{}里面有效,如果在外部引用就会报错. { let a = 10; var b = "hello" } ale ...
- ES6学习笔记(1)----let和const命令
参考书<ECMAScript 6入门>http://es6.ruanyifeng.com/ let和const命令 let 总结1.声明变量基本使用方法与var 相同 不同点 a.在代 ...
- ES6学习笔记之 let与const
在js中,定义变量时要使用var操作符,但是var有许多的缺点,如:一个变量可以重复声明.没有块级作用域.不能限制修改等. //缺点1:变量可以重复声明 var a=1; var a=2; conso ...
- ES6学习笔记<一> let const class extends super
学习参考地址1 学习参考地址2 ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015:也 ...
- es6学习笔记-class之一概念
前段时间复习了面向对象这一部分,其中提到在es6之前,Javasript是没有类的概念的,只从es6之后出现了类的概念和继承.于是乎,花时间学习一下class. 简介 JavaScript 语言中,生 ...
- ES6学习笔记<五> Module的操作——import、export、as
import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...
- ES6学习笔记<四> default、rest、Multi-line Strings
default 参数默认值 在实际开发 有时需要给一些参数默认值. 在ES6之前一般都这么处理参数默认值 function add(val_1,val_2){ val_1 = val_1 || 10; ...
- ES6学习笔记<三> 生成器函数与yield
为什么要把这个内容拿出来单独做一篇学习笔记? 生成器函数比较重要,相对不是很容易理解,单独做一篇笔记详细聊一聊生成器函数. 标题为什么是生成器函数与yield? 生成器函数类似其他服务器端语音中的接口 ...
- ES6学习笔记<二>arrow functions 箭头函数、template string、destructuring
接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...
随机推荐
- 彻底领悟javascript中的exec与match方法
exec是正则表达式的方法,而不是字符串的方法,它的参数才是字符串,如下所示: var re=new RegExp(/\d/); re.exec( "abc4def" ); //或 ...
- vue - 详细路由配置
1. 路由可配置多个 2. 路由包含嵌套子路由 3. 路由可以别名 4. 路由单独钩子 5. vue2.6.0(可以直接匹配大小写) export default new Router({ mode: ...
- 解压zip,解决中文乱码
Project p = new Project(); Expand e = new Expand(); e.setProject(p); e.setSrc(f ...
- 算法笔记_012:埃拉托色尼筛选法(Java)
1 问题描述 Compute the Greatest Common Divisor of Two Integers using Sieve of Eratosthenes. 翻译:使用埃拉托色尼筛选 ...
- 算法笔记_020:深度优先查找(Java)
目录 1 问题描述 2 解决方案 2.1 蛮力法 1 问题描述 深度优先查找(depth-first search,DFS)可以从任意顶点开始访问图的顶点,然后把该顶点标记为已访问.在每次迭代的时候, ...
- MySQL定位锁争用比较严重的表
1:查看当前的事务 mysql> SELECT * FROM information_schema.innodb_trx \G 2:查看当前锁定的事务 mysql> SELECT * FR ...
- Nginx如何保留真实IP和获取前端IP
原理: squid,varnish以及nginx等,在做反向代理的时候,因为要代替客户端去访问服务器,所以,当请求包经过反向代理后,在代理服务器这里这个IP数据包的IP包头做了修改,最终后端web服务 ...
- Java同步机制总结--synchronized
不久前用到了同步,现在回过头来对JAVA中的同步做个总结,以对前段时间工作的总结和自我技术的条理话.JAVA中synchronized关键字能够 作为函数的修饰符,也可作为函数内的语句,也就是平时说的 ...
- 〖Fedora〗设置Fedora静态ip地址
root@Fedora:~# cat /etc/sysconfig/network-scripts/ifcfg-eth0 # Intel Corporation 82540EM Gigabit Eth ...
- Cookie技术
u 常用的API 创建Cookie对象 Cookie(String name, String value) ->以指定数据创建Cookie对象 设置Cookie对象 void setMa ...