let是ES6變量類型,其只在代碼塊內有效。
閉包是有函數以及創建該函數的詞法環境組合而成,這個環境包含了這個閉包創建時所能訪問的所有局部變量。
如果合理使用閉包,可以使用var實現let局部有效的效果。顯然這是多餘的,因為babel已經能幫我們做了,並且很多新版瀏覽器都支持let,所有本文結束。
等等,babel都幹了啥?為啥能將let轉碼使代碼兼容舊版瀏覽器?
兼容轉碼
我們先來看一段比較簡單的babel轉碼
我們來搬一段特別複雜的let類型申明代碼
在babel官網將其轉碼為兼容代碼:
老司機馬上就看出了:將let轉為了閉包
閉包
我們來看看MDN上的一段例子
閉包是由函數以及創建該函數的詞法環境組合而成。這個環境包含了這個閉包創建時所能訪問的所有局部變量。
我們一通分析便可以看出
code4的閉包是立即執行
利用閉包,使var == let
code4的結構不正是code2的簡寫嗎?我們可以將code2改寫為
說好的簡寫呢?!
仔細閱讀這句話閉包是由函數以及創建該函數的詞法環境組合而成。這個環境包含了這個閉包創建時所能訪問的所有局部變量。
let是塊級作用域,也就是局部作用域。閉包也是能訪問局部作用域。
code4
在let出現之前,在循環中寫閉包是一個比較常見的問題。
我們不鼓勵在循環中創建閉包,過多的閉包會付出性能代價。
Babel的bug
意外發現了一個Babel的小bug。我們在最新的Chrome/Firefox瀏覽器中運行這段代碼:
會發現輸出結果為3次”abc 1539160907***”。將code6通過Babel轉碼得到code7
code7在瀏覽器中僅僅運行了1次,輸出結果為”abc 1539160907***”
阮老師講:
for循環還有一個特別之處,就是設置循環變量的那部分是一個父作用域,而循環體內部是一個單獨的子作用域。