很久沒有寫部落格,日子一天天過得很快,覺得有時候寫點東西會讓人沉靜下來邊思考邊整理,一直糾結let是個什麼東西,看了些面試題好多都關於這個的,今天終覺恍然大悟啊,然後整個人就開心起來了,終究學習還是使人快樂啊!
進入正題吧~~
首先我們說一下塊級作用域的定義:任何一對花括號({和})中的語句集都屬於乙個塊,在這之中定義的所有變數在**塊外都是不可見的,我們稱之為塊級作用域。
/*利用匿名函式表示式可以模擬出塊級作用域*/
(function ())();
除此之外我們可以用let來實現塊級作用域。
es6 新增了let
命令,用來宣告變數。它的用法類似於var
,但是所宣告的變數,只在let
命令所在的**塊內有效。
沒有塊級作用域會帶來什麼樣的麻煩呢?
1.由於es5只有全域性作用域和函式作用域,沒有塊級作用域,會帶來很多問題,比如說向下面的例子,內層變數可能會覆蓋外層變數。
var tmp = new date();
function f()
}f(); // undefined
上面**的原意是,if
**塊的外部使用外層的tmp
變數,內部使用內層的tmp
變數。但是,函式f
執行後,輸出結果為undefined
,原因在於變數提公升,導致內層的tmp
變數覆蓋了外層的tmp
變數。
2.用來計數的迴圈變數洩露為全域性變數。
var s = 'hello';
for (var i = 0; i < s.length; i++)
console.log(i); // 5
上面**中,變數i
只用來控制迴圈,但是迴圈結束後,它並沒有消失,洩露成了全域性變數。
let實現塊級作用域例子:
function f1()
console.log(n); // 5
}
上面的函式有兩個**塊,都宣告了變數n
,執行後輸出5。這表示外層**塊不受內層**塊的影響。如果使用var
定義變數n
,最後輸出的值就是10。
let宣告變數的特點:
1.var
命令會發生」變數提公升「現象,即變數可以在宣告之前使用,值為undefined
。這種現象多多少少是有些奇怪的,按照一般的邏輯,變數應該在宣告語句之後才可以使用。
為了糾正這種現象,let
命令改變了語法行為,它所宣告的變數一定要在宣告後使用,否則報錯。
// var 的情況
console.log(foo); // 輸出undefined
var foo = 2;
// let 的情況
console.log(bar); // 報錯referenceerror
let bar = 2;
2.只要塊級作用域內存在let
命令,它所宣告的變數就「繫結」(binding)這個區域,不再受外部的影響。
var tmp = 123;
if (true)
上面**中,存在全域性變數tmp
,但是塊級作用域內let
又宣告了乙個區域性變數tmp
,導致後者繫結這個塊級作用域,所以在let
宣告變數前,對tmp
賦值會報錯。
es6明確規定,如果區塊中存在let
和const
命令,這個區塊對這些命令宣告的變數,從一開始就形成了封閉作用域。凡是在宣告之前就使用這些變數,就會報錯。
總之,在**塊內,使用let
命令宣告變數之前,該變數都是不可用的。這在語法上,稱為「暫時性死區」(temporal dead zone,簡稱 tdz)。
3.let
不允許在相同作用域內,重複宣告同乙個變數。
/ 報錯
function ()
// 報錯
function ()
以上是學習自阮一峰老師的ecmascript 6入門,我覺得介紹得非常清楚,適合對初學ecmascript 6的孩子們。**:
es6中let和const 塊級作用域
在es6之前,我們都是用 var 關鍵字宣告變數。無論宣告在何處,都會被視為宣告在函式的最頂部 不在函式內即在全域性作用域的最頂部 這就是函式變數提公升 例如 functionaa else 變數宣告後 實際上是 functionaa else 此處訪問 test 值為 undefined 所以不用...
es6 塊級作用域用法
iife 寫法 function 塊級作用域寫法 塊級作用域的出現,實際上使得獲得廣泛應用的立即執行函式表示式 iife 不再必要了。function f function f 上面 在 es5 jscript不支援塊級作用域環境中執行,會得到 i am inside 因為在 if內宣告的函式f會被...
ES6的塊級作用域
為什麼要使用塊級作用域?1.在預編譯階段,變數的宣告會被提公升到作用域頂部,而初始化操作依舊留在原處執行,在該作用域中未定義變數的地方也能訪問到該變數,但是此時變數尚未初始化,所以其值為undefined,為此es6引入塊級作用域來強化對變數生命週期的控制 塊級宣告 1.塊級作用域用於宣告在指定塊的...