基本用法
let是ES6中新添加的命令,用来声明变量,用法类似var,但是所声明的变量,只在let命令所在的代码块内有效,如:
1 2 3 4 5 6
| for(var i=0;i<1;i++){ var b = 3; let c = 4; } console.log(b); // 输出为:3 console.log(c); // 出错
|
在代码块之外调用这两个变量,结果let声明的变量报错,var声明的变量返回了正确的值。
这表明,let声明的变量只在它所在的代码块有效。
再如下面的计数器代码:
1 2 3 4 5 6 7
| var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10
|
由于var声明的变量在整个作用域中都有用,所以每一次循环,新的i值都会覆盖旧值,导致输出的是最后一轮的i的值,也就是 10 。
如果用循环输出ai,所有的值都是 10 。
1 2 3 4 5 6 7
| var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 6
|
由于let声明的变量只能在当前的代码块中都有用,所以每一次循环,相当于创建了一个新的变量i,所以每次输出的都是当前代码块中的i 。
如果用循环输出ai,得到的就是当前的 i 。
无变量提升
1 2 3 4 5
| console.log(foo); // 输出undefined console.log(bar); // 报错 var foo = 2; let bar = 2;
|
var变量会被提升到代码块的最前面声明,而let不会,输出的时候就会报错。
变量区域绑定
1 2 3 4 5 6
| var a = 123; if (true) { a = 'abc'; // 报错 let a; }
|
上面声明了一个局部变量a,导致后者绑定这个块级作用域,所以在let声明变量前,对a赋值会报错。
总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称TDZ)
1 2 3 4 5 6 7 8 9 10 11
| if (true) { // TDZ开始 tmp = 'abc'; // 报错 console.log(tmp); // 报错 let tmp; // TDZ结束 console.log(tmp); // undefined tmp = 123; console.log(tmp); // 123 }
|
不允许重复声明
let不允许在相同作用域内,重复声明同一个变量。
1 2 3 4 5 6 7 8 9
| // 报错 function () { var a = 3 ; // 报错 let a = 10; // 报错 let a = 1; // 报错 if(true){ let a = 6 ; // 正确 } }
|
全部let变量不属于顶层变量
var变量也是window顶层变量,而let变量不再属于window对象。
1 2 3 4 5 6
| var a = 1; window.a // 1 thiw.a 1 let b = 1; window.b // undefined
|
本文地址:
http://wsdever.github.io/2016/10/01/20161110/