<深刻理解ES6>一書中,提起 let/const 這也是日常工做用的比較多,最近須要給公司作培訓. 從新複習下以往的知識點.javascript
本文首發自 github 我的博客. 轉載請註明出處. 來這裏討論前端
再聊 let/const
以前, 讓咱們回顧下咱們的老朋友 var
, 他有什麼特色或特性java
經過下面的例子, 能夠複習下, 關鍵字var
聲明帶來的影響.node
console.log(typeof A) // 'function'
console.log(a) // undefined
console.log(typeof a) // 'undefined'
console.log(typeof Date) // 'function'
console.log(window.Date) // function Date() {}
function A() {
console.log(new Date())
}
var a = 10
var Date = 1000
console.log(window.Date) // 1000
複製代碼
因爲變量提高
的緣故, function 優先於 var提高且定義,此時 a只聲明,未賦值,函數已聲明且賦值.git
一樣的代碼,把window
改爲global
放在node裏面運行發現結果又不同, global.Date
沒有被從新賦值, 是由於在node運行環境裏面, node 出於代碼安全考慮, 每個文件最終變成了由 require('module').wrapper
方法包裹起來, 每個node的 js 文件, 須要 經過exports或module.exports暴露出模塊的方法和屬性才能使用.github
因而可知 var聲明
會帶來如下影響面試
一般的習慣多是, 放在 top scope 的位置, 做爲一個規範來約束本身或團隊.數組
但並非每一個人都能很好的按照規範來作, 因而ES6 推出了 let/const來解決var聲明
的弊端安全
把上面的代碼換成 let
app
console.log(a) // Uncaught ReferenceError: Cannot access 'a' before initialization
console.log(typeof a) // 'undefined'
console.log(typeof Date) // 'function'
console.log(window.Date) // function Date() {}
複製代碼
以前執行的 console.log(a)
直接報錯, 阻止程序運行.
直接運行console.log(typeof a)
也同樣, 而不作任何聲明的時候, 會輸出 'undefined'
.
let a = 10
let Date = 1000
console.log(window.Date) // function Date() {}
console.log(a) // 10
console.log(Date) // 1000
console.log(window.a) // undefined
複製代碼
正常邏輯執行後, 並無想象中, window.a
和a
相等. 產生上面現象的緣由是什麼呢??
在let/const
聲明前訪問其變量會形成初始化以前不能訪問
,這種現象叫作 TDZ.
上述例子中, a
和Date
聲明後並無污染 window.a
和window.Date
, 所以當使用的時候須要覆蓋的時候使用 let/const
聲明的變量, 須要手動覆蓋.
早年有一個經典的面試題, 叫作 建立10 個 div.點擊輸出對應的索引.
筆者在初次寫 js 的時候, 寫成了這種錯誤形式
// bad way
for(var i = 0; i < 10; i++) {
var div = document.createElement('div')
div.className = 'item'
div.innerHTML = i
div.onclick = function() {
alert(i)
}
document.body.appendChild(div)
}
複製代碼
輸出的結果也每每是 10, 需求是點擊索引啊. 形成這種結果的緣由是
var變量提高, 當點擊的時候此時 i 是 10
所以咱們經常用 IIFE(即時執行函數)
// good way
for(var i = 0; i < 10; i++) {
var div = document.createElement('div')
div.className = 'item'
div.innerHTML = i
div.onclick = (function(i) {
return function() {
alert(i)
}
})(i)
document.body.appendChild(div)
}
複製代碼
那有木有更好的方案, 能不能每次 循環的時候建立一個新的 i, let
具有這一特性
// better way
for (let i = 0; i < 10; i++) {
let div = document.createElement("div");
div.className = "item";
div.innerHTML = i;
div.onclick = function() {
alert(i)
}
document.body.appendChild(div);
}
複製代碼
const
用來保存常量, let 在修改的使用. const 對對象處理的時候, 對象/數組屬性賦值還能夠修改.
關於對象的常量問題, 放到後面章節整理.