let的特性
1,介绍
1.1. 作用:
- 与var类似, 用于声明一个变量
1.2. 特点:
- 可以将变量的作用域限定在任意代码块中。
- 不能重复声明(无论之前是var还是let声明)
- 不会预处理, 不存在提升
- 可以只声明,不赋值
1.3. 应用:
- 循环遍历加监听
- 使用let取代var是趋势
2,测试
测试1
let关键字,可以将变量的作用域限定在任意代码块中。
var topic = 'JavaScript'if (topic) { let topic = 'inner' console.log(topic) // inner}console.log(topic) // JavaScript复制代码
测试2
0 1 2 3 4 循环 5次,共 25个数
如果是var,则只会循环 1次,共 5个数,因为使用var,定义的变量是全局的
for(let i=0; i<5; i++) { for(let i=0; i<5; i++) { console.log(i); }}复制代码
测试3
for (let x...)循环,每次迭代时都为x创建新的绑定
var a = [];for (var i = 0; i < 10; i++) { // 使用var,for循环是不会有作用域的 a[i] = function () { // 函数有作用域 console.log(i); };}a[6](); // 10复制代码
下面展示的是,上面的代码中,var替换为let时,实际执行的过程:
var a = [];{ let k; for (k = 0; k < 10; k++) { let i = k; // 注意这里,每次循环都会创建一个新的i变量 a[i] = function () { console.log(i); }; }}a[6](); // 6复制代码
测试4
这个会报错,
运行机制,只要目标作用域中有let声明的变量,就不会向外找!即便运行时没有。
let num = 10;(function() { console.log(num); let num = 20;})();复制代码
测试5
在程序或者函数的顶层,let并不会像var一样在全局对象
window
上创造一个属性
var x = 'global';let y = 'global';console.log(this.x); // "global"console.log(this.y); // undefined//this指向window,所以var声明的,也是undefined(function () { var x = 'global'; let y = 'global'; console.log(this.x); // undefined console.log(this.y); // undefined})();复制代码
测试6 暂存死区的错误
因为switch中,只有一个块
switch (x) { case 0: let foo; break; case 1: let foo; // TypeError for redeclaration. break;}//所以,需要添加块级作用域switch(x) { case 0: { let foo; break; } case 1: { let foo; break; }}复制代码
测试7 词法作用域
与词法作用域结合。
由于词法作用域,表达式(foo + 55)内的标识符“foo”会解析为 if 块的foo,而不是覆盖值为33的foo, 而foo已经创建,但尚未达到(并终止)其初始化(这是语句本身的一部分),所以报错。
function test(){ var foo = 11; if (true) { let foo = (foo + 22); // ReferenceError }}test();复制代码
指令
因此标识符“n.a”被解析为位于指令本身的第一部分(“let n”)中的'n'对象的属性'a' ,由于尚未达成和终止其声明,因此仍处于暂存死区let n of n.a
已经在for循环块的私有范围内,
function go(n) { // n here is defined! console.log(n); // Object {a: [1,2,3]} for (let n of n.a) { // ReferenceError console.log(n); }}go({a: [1, 2, 3]});复制代码