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();
复制代码
指令
let n of n.a
已经在for循环块的私有范围内,
因此标识符“n.a”被解析为位于指令本身的第一部分(“let n”)中的'n'对象的属性'a' ,由于尚未达成和终止其声明,因此仍处于暂存死区
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]});
复制代码