一、 關鍵字 let
正如大家都熟悉的,我們平時在寫代碼的時候,用var 聲明一個變量,除此之外,也再沒有接觸到其它的關鍵字了,不管我們聲明什麼樣類型得變量,都用var 搞定了,很友善,但是ES6 告訴你,除了var,還可以試試 let 來聲明變量。
那麼,既然var 友善,為什麼還要let 來聲明,這麼說 var 聲明 一定會有不足的地方。
下面介紹 用 var 的不足之處。
1.先看一段代碼
var arr = [ ];
for(var i=0; i<10; i++){
arr [i] = function(){
alert(i)
}
}
arr [1](); //結果:10
很明顯,我們執行這段代碼的想要的結果是彈出arr 這個數組對應索引的值。但發現無論索引是幾 彈出結果都是10。
Why ?
繼續執行這段代碼看看:
var arr = [ ];
for(let i=0; i<10; i++){
arr[i] = function(){
alert(i)
}
}
arr[1](); //結果:1
居然彈出了對應索引的值!對比一下兩段代碼,唯一的不同之處就是循環的時候初始化變量 i 是使用let,而不是用var, Why ? ?
原來,let聲明的變量僅僅在自己使用的塊級作用域起作用,出了這個塊級作用域就不起作用了。
注意:塊級作用域 即任何一對花括号中的語句都屬于一個快,在花括号用let 定義的所有變量在花括号外都是不可見的,我們稱之為 塊級作用域。
那麼回到代碼中,for循環含有{ },也就是含有了塊級作用域,每個變量 i 都隻是在自己的作用域起作用,例如:第10次循環中的 i 的值不會影響到到第9次循環。
ok!
2.var 聲明變量會出現“變量提升“。
What ?
上代碼:
var a = 1;
(function(){
alert(a);
var a = 2;
})();//結果:undefined
猛的一看,結果不應該是 1 嗎,為什麼會是未定義呢?
原因就在于我們在代碼塊(函數内)裡面還聲明并定義了一個變量a,導緻變量提升了,實際的代碼執行順序是這樣的,認真看完你就明白道什麼叫變量提升了。
var a = 1;
(function(){
var a;
alert(a);
a = 2;
})();
對比一下兩段代碼:var a = 2; 這句代碼被拆分成兩部分:聲明var a ; 和 定義a = 2;而聲明部分被提升了,到了代碼塊的前面,運作的時候自己挪到前面了,這就是“變量提升“,結果就是:先執行聲明,接着就執行alert(a);變量a隻是聲明還沒定義,就彈出了undefined了。
那麼,用let關鍵字在代碼塊就不會被提升了嗎? 确定以及肯定。
var a = 1;
(function(){
alert(a);
let a = 2;
})(); // 結果:報錯a未定義
那為什麼又報錯了呢,因為用let聲明的變量,在其塊級作用域内是封閉的,是不會受到外面的全局變量a影響的,并且要先聲明再使用,是以a的值即不是1(因為不受外面的影響),也不是undefined(因為先聲明後使用),更不是2,未聲明定義就使用,那隻有報錯了。
注意:let關鍵字要記得先聲明定義再使用。
3.使用let 其它注意點
(1) 同一個塊級作用域内,不允許重複聲明同一個變量。
錯誤執行個體:
{
var a =1;
let a =2; //報錯,因為a已經用var聲明過
}
{
let a =1;
let a= 2; // 還是報錯,a已經用let聲明過。
}
(2) 函數内不能用let重新聲明函數的參數
function say(name){
let name = 'zhang'; //報錯:用let重新聲明name參數
alert(name)
}
say('wang');
say()函數内用let重新聲明了name這個參數,No!
小結:
用 let 聲明變量隻在塊級作用域起作用,适合在 for 循環使用,也不會出現變量提升現象。同一個代碼塊内,不可重複聲明的相同變量,不可重複聲明函數内的參數。
原文釋出時間為:2018年02月03日
原文作者:
前端喵本文來源:
開源中國如需轉載請聯系原作者