你不知道的JavaScript-提升

vuestar發表於2018-02-03

提升

提升現象的出現,是因為程式碼在執行前,引擎會先進行編譯。這個過程就好像變數和函式宣告從它們在程式碼中出現的位置被“移動”到了最上面。

準則

  1. 只有宣告本身會被提升,而賦值或其他執行邏輯會留在原地。
  2. 每個作用域都會進行提升操作。
  3. 函式宣告會被提升,但是函式表示式卻不會被提升。
  4. 函式宣告和變數宣告都會被提升,是函式會首先被提升,然後才是變數。
  5. let和const進行的宣告不會再塊作用域中進行提升。

例子

示例1

console.log(a);
var a = 2;
複製程式碼

編譯後的結果是:

var a;
console.log(a); // undefined
a = 2;
複製程式碼

示例2

foo();

function foo() {
	console.log(a);
	var a = 2;	
}
複製程式碼

編譯後的結果是:

function foo() {
	var a;
	console.log(a); // undefined
	a = 2;
}
foo();
複製程式碼

原理參見第2條。

示例3

foo();

var foo = function() {
	console.log(2);
};
複製程式碼

編譯後的結果是:

var foo;

foo(); // 不是ReferenceError,而是TypeError

foo = function() {
	console.log(2);
};
複製程式碼

原理參見第三條。

示例4

foo();

var foo;

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

foo = function() {
	console.log(2);
}
複製程式碼

編譯後的結果是:

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

foo(); // 1

foo = function() {
	console.log(2);
}
複製程式碼

原理見第4條,函式被提升,然後重複宣告的變數忽略。但如果重複宣告的是函式,則發生覆蓋操作,如下:

foo(); // 3

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

var foo = function() {
	console.log(2);
};

function foo() {
	console.log(3);
}
複製程式碼

編譯後的結果是:

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

foo(); // 3

foo = function() {
	console.log(2);
};
複製程式碼

相關文章