JavaScript中var與let區別
今日頭條:https://www.toutiao.com/i6535675554807415299/?tt_from=weixin&utm_campaign=client_share&wxshare_count=1&from=singlemessage×tamp=1541120454&app=news_article&utm_source=weixin&iid=44628601808&utm_medium=toutiao_android&group_id=6535675554807415299
JavaScript中var與let區別
ES6引入let關鍵字,在JS中var與let都是用來宣告變數,var沒有塊級作用域,let有。let因為有了塊級作用域,還會帶其他的不同。
現在來具體舉例說明下區別:
1、關於塊級作用域
var a = 0;
{
var a = 1;
}
console.log(a); // 1
如果是let:
let a = 0;
{
let a = 1;
}
console.log(a); // 0
2、重定義同名變數
var b = 1;
var b = 2;
console.log(b); // 2
var b = 1;
{
var b = 2;
}
console.log(b); // 2
如果是let:
let b = 1;
let b = 2; // 報錯。Identifier ‘b’ has already been declared
let b = 1;
{
let b = 2;
}
console.log(b); // 1
3、變數提升
var a = 1;
function foo() {
console.log(a); // undefined
var a = 2;
}
foo();
如果是let則拋異常。 a is not defined
4、全域性物件屬性
var a = 1;
console.log(window.a, a); // 1,1
如果是let:
let b = 1;
console.log(window.b, b); // undefined, 1
5、for(含for-of、for-in)迴圈中的不同,let會建立一個新的作用域
for (var i = 0; i < 3; i++) {
setTimeout(function() {
console.log(“setTimeout:”, i); // 3次3
});
}
如果是let:
for (let i = 0; i < 3; i++) {
setTimeout(function() {
console.log(“setTimeout:”, i); // 0,1,2
});
}
這是為什麼?每次都會宣告新的同名變數嗎?那怎麼遞增和怎麼影響到外部呢?
1.for(expression) 括號裡面表示式是一個父級作用域
2.for迴圈的每個迭代都會建立一個新的{}作用域塊,也就有了塊級作用域。新的塊是基於前一個執行環境所建立,在初始化時會把變數宣告和最新賦值都帶過來(thisIterationEnv.InitializeBinding (bn, lastValue))。因此變數會跟著遞增,同時如果修改了{}塊中的變數也會影響到表示式作用域中的同名變數。但如果在{}塊內顯式地聲明瞭同名變數,則此時變數修改就不會影響到父級。
3.var允許重複宣告覆蓋外層同名的變數,let因為塊級作用域所以不會覆蓋父級同名的變數
迴圈就像以下:
var i = 1; i++;
{
var i = i; // i = 2
setTimeout(function() {
console.log(i); // 3
}, 0);
}
i = 3;
console.log(i); // 3
如果是let:
let i = 1; i++;
{
let i = 2;
setTimeout(function() {
console.log(i); // 2
}, 0);
}
i = 3;
console.log(i); // 3
再看一段程式碼:
for (let i = 0; i < 3; i++, console.log(“expression作用域:”, i)) {
setTimeout(function() {
console.log(“setTime function作用域:”, i);
});
let i = 10; // 刪除這行試下
i++;
console.log(“for block作用域:”, i);
}
執行結果:
JavaScript中var與let區別