let關鍵字
let是在ES6引入的新關鍵字,其主要用於定義塊作用域的變量。
當變量有let定義時,作用如下
1.將變量綁定所在的任何作用域中,通常是{…}
我們知道 var聲明的變量將會綁定在包圍該變量的函數作用域內。注意是函數作用域,並非{}代碼塊。
常見的是將變量綁定子for循環內
eg:
//混淆點
var foo = true, baz = 10;
if (foo) {
var bar = 3;
}
/*習慣了強類型的語言的會習慣性地認爲,if塊外是無法訪問bar的,其實這裏 var 定義的變量是被綁定在了window全局中*/
if (baz > bar) {
console.log( baz );
}
function bar(){
for(var i=0;i<3;i++){
}
console.log(i)//,此處i被綁定在bar的作用內。
}
bar(); //2
//利用let將i綁定在for循環內部
funcion foo(){
for(let i=0;i<3;i++){
}
consoel.log(i);
}
foo(); //ReferenceError: i is not defined,i能在for循環裏面被訪問
2.防止變量提升
變量提升,很簡單,就是把變量提升提到函數的top的地方。我麼需要說明的是,變量提升 只是提升變量的聲明,並不會把賦值也提升上來。
eg:
console.log(a); //unddfined,未報錯,var聲明的變量會發生變量提升
var a=2;
console.log(a);//出錯a is not defined,未定義
let a=2;
說到變量提升,看到一個有趣的題目
var str='hello world'
function bar(){
console.log(str);
var str='hello bar';
}
bar();//輸出什麼
答案解析:輸出undfined,其原因是js的作用域鏈和變量提升的原因,在console.log(str)時,根據作用域鏈的查找規則,首先查找bar函數內是否有str變量,由變量提升,str的聲明(非賦值)會被提到console.log的前面,所以變量查找會查找到bar函數內的str;
3.禁止重複聲明在同一個作用域內已聲明的標示符
var a=1;
let a //a 標識符已經定義,重複定義出錯,但 var a=2;不會出錯
4.let聲明的全局變量不會被添加到window屬性上,防止了對全局對象的污染
var a=1;
console.log(window.a) //1 var聲明的全局變量會會被賦到window屬性中。
let b=2;
console.log(window.b)//undefined, let聲明的全局變量不會掛載到全局對象window中,從而防止了對window對象的污染。