[深刻理解ES6]let/const/var

<深刻理解ES6>一書中,提起 let/const 這也是日常工做用的比較多,最近須要給公司作培訓. 從新複習下以往的知識點.javascript

本文首發自 github 我的博客. 轉載請註明出處. 來這裏討論前端

let/const

再聊 let/const以前, 讓咱們回顧下咱們的老朋友 var, 他有什麼特色或特性java

var

經過下面的例子, 能夠複習下, 關鍵字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/const

把上面的代碼換成 letapp

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.aa相等. 產生上面現象的緣由是什麼呢??

暫時性死區(temporal dead zone, TDZ)

let/const聲明前訪問其變量會形成初始化以前不能訪問,這種現象叫作 TDZ.

let/const不會對 scope 域名作覆蓋/污染

上述例子中, aDate聲明後並無污染 window.awindow.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 對對象處理的時候, 對象/數組屬性賦值還能夠修改.

關於對象的常量問題, 放到後面章節整理.

相關文章
相關標籤/搜索