本文是在看完阮一峯老師的著作只會所總結的~~~~
給阮老師致敬,同時也可以去阮老師的的書裏看 ~~
http://es6.ruanyifeng.com/#docs/let
另外若要看如何使用搭配es6環境,請看我的上一條博客
ECMAScript6.0是下一代的js語言標準,於2015.6發佈。
let是ES6新增的用法,用來聲明變量的,用法類似於var。但其又有獨特的作用。
一:看看let和var的差別
說明:下面所敲得代碼都在嚴格模式下,前面添加“use strict”
1.變量聲明:
{
let a=10;
var b=1;
}
console.log(a); //會報錯 ReferenceError: a is not defined 因爲a只在前面的代碼塊中有效。
console.log(b);//1
輸入a會出現錯誤,而b則輸出正確結果。因爲let命令是在塊級作用域有效,所謂塊級作用域就是{}括起來的。
2.for循環:
var a=[];
for(var i=0;i<10;i++){
a[i]=function(){
console.log(i);
}
}
a[6](); //10 因爲用var聲明的i,所以在全局範圍內都是有效的,所以每一次循環都會導致i++,最後輸出最後一輪i的值
//如果換成let聲明,則只會輸出6。因爲當前的i只會在本次循環有效,不疊加到下次循環裏面,所以每一次輸出的i都是一個新的變量。
再舉一個例子:
for(let i=0;i<10;i++){
console.log(i);//輸出0~9
}
這裏輸出0~9的數字而不會直接輸出9,是因爲let只在本次循環有效,所以循環一次就會輸出一個值。
3.變量提升:
let在同一作用域內不存在變量的提升。也就是使用前先聲明。
if(true){
console.log(tmp); //ReferenceError: tmp is not defined
let tmp;
console.log(tmp); //undifined
}
有可能你測試的結果會有點不一樣,那是因爲採用了babel轉碼,babel會先將let轉爲var再使用。而var是有變量提升的。
如果你在cmd或者其他地方運行,基於node xx.js 和babel-node xx.js將會得到不同的結果。
本文所有代碼都沒有進行轉碼,只在Node環境下運行。
4.同一作用域不允許重複的聲明一個變量:
if(true){
console.log(tmp);
let tmp;
lettmp="123";
console.log(tmp);
}
//會報錯 Duplicatedeclaration "tmp" 同一作用域中不能用let聲明相同的變量。而我們的var是可以重複聲明的,只是後面的值將覆蓋前面的值。
5.暫時性死區:
暫時性死區的本質就是,只要一進入當前作用域,所要使用的變量就已經存在了,但是不可獲取,只有等到聲明變量的那一行代碼出現,纔可以獲取和使用該變量。
具體案例:
var tmp=123;
if(true){
tmp='abc';
let tmp;
console.log(tmp);//ReferenceError: tmp is not defined
}
//var定義了一個tmp,所以存在一全局變量tmp,但是如果塊級作用域內又用let聲明瞭一遍tmp,導致後者綁定了這個塊級作用域,而且在變量聲明之前就使用了tmp,所以導致輸出的結果爲ReferenceError: tmp is not defined ,如果將let tmp移動到tmp='abc'上去,則會輸出abc。
二:關於塊級作用域:
1.保證每一個變量都有其單獨的值,不用擔心被覆蓋。
2.不用擔心內部的變量會泄露成全局變量。
3.內層作用域可以定義外層作用域的同名變量。如果一個變量嵌套了多個塊級作用域,外面的作用域是無法讀取內部的作用域的。也就是不同的作用域變量是互不相關的。
例如
{{{{
let a = 'a';
{let a= 'b'}
}}}};
可以得出幾點結論:塊級作用域是可以任意嵌套{}的。內部的{}可以定義和外部的{}同樣的變量名。
{ let a='a'}括號內是隻能調用本括號內的值,無法讀取到內部的值,所以其結果只能輸出a。
而內部變量是可以調用外部變量的值, { let a = 'a';{console.log(a)}},是可以輸出a。
4.ES6裏面不需要匿名函數,而直接{}就可以執行。
(function () {
var tmp = ...;
...
}());
// 塊級作用域寫法
{
let tmp = ...;
...
}
三:關於塊級作用域的函數聲明:
允許在塊級作用域內聲明函數。函數聲明類似於var
,即會提升到全局作用域或函數作用域的頭部。同時,函數聲明還會提升到所在的塊級作用域的頭部。
函數聲明的用法和Let也有點相似,外層函數不能調用裏層塊級作用域的函數。
並且所有的聲明只能在有大括號{}的時候成立,沒有將會出錯。