1. 程式人生 > >var/let/const變數提升

var/let/const變數提升

var宣告的建立、初始化和賦值過程
console.log(a);
var a = 1;

在執行過程中,會有以下過程:

  1. 在全域性環境中建立用var宣告的這些變數,即a
  2. 將這些變數初始化為undefined
  3. 執行console.log(a)
  4. a = 1將變數為1
let/const宣告的建立、初始化和賦值過程
{
	let x = 1;
	x = 2;
}
  1. 找到所有用let宣告的變數,在環境中建立這些便利
  2. 開始執行變數(注意現在還沒有初始化)
  3. 執行x = 1,將x初始化為1(這並不是一次賦值,如果程式碼是let x,就將x初始化為undefined)
  4. 執行x = 2,對x進行賦值
x = 1;
function test(){
	console.log(x); // Uncaught ReferenceError: x is not defined
	let x = 2;
}
test()

所以我理解為let/const是存在變數提升的(我的理解:如果let/const不存在變數提升,那麼在let定義之前訪問的x應該是全域性定義的x即1),只是因為let/const存在一個暫時性死區所以在初始化之前無法訪問:

The variables are created when their containing Lexical Environment is instantiated but may not be accessed inany way until the variable’s LexicalBinding is evaluated.

翻譯成中文:

當程式的控制流程在新的作用域(module function 或 block 作用域)進行例項化時,在此作用域中用let/const宣告的變數會先在作用域中被創建出來,但因此時還未進行詞法繫結,所以是不能被訪問的,如果訪問就會丟擲錯誤。因此,在這執行流程進入作用域建立變數,到變數可以被訪問之間的這一段時間,就稱之為暫時性死區。

function宣告的建立、初始化和賦值過程
f2()
function fn2(){
	console.log(2);
}
  1. 找到所有用function宣告的變數,在環境中建立這些變數
  2. 將這些變數初始化並賦值為function(){console.log(2)}
  3. 開始執行fn2()