深刻理解let和var的區別(暫時性死區)!!!

首先咱們應該知道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

那麼let/const和var又有什麼區別呢??

  • let/const是使用區塊做用域;var是使用函數做用域。
  • 在let/const聲明以前就訪問對應的變量與常量,會拋出ReferenceError錯誤;但在var聲明以前就訪問對應的變量,則會獲得undefined。
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

相關文章
相關標籤/搜索