首先咱們應該知道js引擎在讀取js代碼時會進行兩個步驟:javascript
所謂解釋就是會先通篇掃描全部的Js代碼,而後把全部聲明提高到頂端,第二步是執行,執行就是操做一類的。java
a = 'javascript'; var a; console.log(a);//'javascript'
console.log(b);//undefined var b='javascript'
遇到 script 標籤的話 js 就進行預解析,將變量 var 和 function 聲明提高,但不會執行 function,而後就進入上下文執行,上下文執行仍是執行預解析一樣操做,直到沒有 var 和 function,就開始執行上下文。如:函數
a=5; show(); var a; function show(){};
預解析:code
function show(){}; var a; a=5; show();
須要注意都是函數聲明提高直接把整個函數提到執行環境的最頂端。ip
console.log(aVar) // undefined console.log(aLet) // causes ReferenceError: aLet is not defined var aVar = 1 let aLet = 2
會出現這樣的狀況是由於let/const擁有「暫時性死區(TDZ)」。作用域
當程序的控制流程在新的做用域(module, function或block做用域)進行實例化時,在此做用域中的用let/const聲明的變量會先在做用域中被建立出來,但所以時還未進行詞法綁定,也就是對聲明語句進行求值運算,因此是不能被訪問的,訪問就會拋出錯誤。因此在這運行流程一進入做用域建立變量,到變量開始可被訪問之間的一段時間,就稱之爲TDZ(暫時死區)。io
結論:let/const聲明的變量,的確也是有提高(hoist)的做用。這個是很容易被誤解的地方,實際上以let/const聲明的變量也是會有提高(hoist)的做用。提高是JS語言中對於變量聲明的基本特性,只是由於TDZ的做用,並不會像使用var來聲明變量,只是會獲得undefined而已,如今則是會直接拋出ReferenceError錯誤,並且很明顯的這是一個在運行期間纔會出現的錯誤。
console
ES6 規定暫時性死區和let、const語句不出現變量提高,主要是爲了減小運行時錯誤,防止在變量聲明前就使用這個變量,從而致使意料以外的行爲。這樣的錯誤在 ES5 是很常見的,如今有了這種規定,避免此類錯誤就很容易啦~function