1.let命令
1.1块级作用域:
和var类似但是只在let声明变量的代码块内有效。例如for循环,每次循环都是不同的代码块,所以let声明的变量在每次循环中都只在当前循环中起作用。
for(vari =0;i <5;i++) {
setTimeout(function() {
console.log(i)
},i *1000)
}输出5次5
解决方法很烦,用闭包
for(vari =0;i <5;i++) {
(function(i) {
returnsetTimeout(function() {
console.log(i)
},i*1000)
}(i))
}
for(leti=0;i<5;i++){
setTimeout(function() {
console.log(i);
},i*1000)
}利用let定义变量的块级作用域很简单,所以let很适合for
1.2不存在变量提升
以前在var声明变量前面我们使用变量,变量值是undefined,不会报错,因为变量提升。
但是用let声明变量的话,不存在变量提升,在声明前使用变量会报错
// var 的情况
console.log(foo);// 输出undefined
varfoo=2;
// let 的情况
console.log(bar);// 报错ReferenceError
let bar=2;
1.3暂时性死区
暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
说明:
只要在块级作用域内用let声明了一个变量,那么let声明的这个变量就相当与绑定了这个块,你在这个块外部定义的同名变量(包括全局),要想在这个块里操作这个变量,都必须得在let声明后使用,否则就会报错。
就连这样都会报错:(因为在使用变量x的时候,x还没有声明完)
// 不报错
varx=x;
// 报错
let x=x; // ReferenceError: x is not defined
1.4不允许在同一个块中重复定义同一个变量,会报错。
1.5在全局下声明的全局对象不再是window顶层对象的属性了。
1.6支持解构赋值
以前,为变量赋值,只能直接指定值。
let a=1;let b=2;let c=3;
ES6允许写成下面这样。
let[a,b,c]=[1,2,3];
1.7do 表达式
本质上,块级作用域是一个语句,将多个操作封装在一起,没有返回值。
{lett=f();t=t*t+1;}
上面代码中,块级作用域将两个语句封装在一起。但是,在块级作用域以外,没有办法得到t的值,因为块级作用域不返回值,除非t是全局变量。
现在有一个提案,使得块级作用域可以变为表达式,也就是说可以返回值,办法就是在块级作用域之前加上do,使它变为do表达式。
letx=do{lett=f();t*t+1;};
上面代码中,变量x会得到整个块级作用域的返回值。