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]});
複製程式碼