JavaScript 變量提高

變量提高是一個將變量聲明或者函數聲明提高到做用域起始處的過程。在本篇博文中,咱們一塊兒深刻了解這個過程的更多細節。javascript

變量的生命週期

當引擎使用變量時,它們的生命週期包含如下階段:java

  • 聲明階段,這一階段在做用域中註冊了一個變量
  • 初始化階段, 這一階段分配了內存並在做用域中讓內存與變量創建了一個綁定,變量會被自動初始化爲 undefined
  • 賦值階段,這一階段爲已初始化的變量分配具體的一個值

注意,聲明階段與咱們一般所說的變量聲明是不一樣的術語。網絡

var 生命週期

網絡不給力

假設這樣一個場景:當解釋器剛進入一個包含 var variable 的做用域時,則在任何語句執行以前,變量就已完成了聲明階段初始化階段,且值爲 undefined。語句 varibale = 'value'賦值階段session

// 在剛進入到 func 做用域時,a 已完成了聲明和初始化階段,且值爲 undefined
function func() {
  console.log(a); // undefined
  var a = 1; // 賦值階段
  console.log(a); // 1
}
func();

function 生命週期

網絡不給力

對於 function聲明、初始化和賦值階段在解釋器剛進入函數做用域時,便已所有完成。函數

能夠結合如下的代碼,去理解 function 的變量提高過程。spa

// function 提高優先級比 var 和 let 高
foo(); // 2

// 具名函數表達式的函數名只在函數內部有效
bar(); // ReferenceError

function foo() {
  console.log(1);
}

// 多個函數聲明時,後面的函數聲明會覆蓋以前的函數聲明
function foo() {
  console.log(2);
}

// 函數聲明會被提高,但函數表達式不會被提高
var foo = function bar() {
  console.log(3);
};

foo(); // 3

let 變量的生命週期

網絡不給力

let 的提高是隻針對聲明階段的提高。code

假設這樣一個場景:當解釋器剛進入一個包含 let variable 的做用域時,就已完成了聲明階段blog

從聲明階段結束到初始化階段開始, 這段區域被稱爲臨時死區。若是在這時訪問 variable ,將會拋出 ReferenceError: variable is not defined生命週期

當解釋器執行完 let variable ,變量就已完成了初始化階段,離開了臨時死區,並具備 undefined 的值。以後的語句 variable = 'value'賦值階段ip

若是解釋器遇到了 let variable = 'value' ,則完成了初始化賦值階段。

總結

至此,總結一下變量提高過程當中的一些重要知識點:

  • var 只有聲明階段初始化階段被提高
  • function聲明階段初始化階段賦值階段都被提高
  • let 只有聲明階段被提高
  • function 提高優先級比 varlet 高,且對於多個函數聲明,後面的聲明會覆蓋前面的聲明
  • 函數表達式沒法被提高

參考資料

相關文章
相關標籤/搜索