1. 程式人生 > >JavaScript提升(你不知道的JavaScript)

JavaScript提升(你不知道的JavaScript)

最近,在讀《你不知道的JavaScript(上卷)》這本書,書中詳細闡述了JavaScript眾多重要但經常被大家忽略的點,在此強烈推薦!!!書中,第4章講述了“提升”,從示例出發講述了變數和函式提升的過程,糾正了自己以前錯誤的理解(相信好多人理解都是錯誤)!
我們習慣將var a = 2;看做一個宣告,而實際上JavaScript引擎不這麼認為!下面幾個示例讓你徹底搞懂JavaScript中的變數提升!
示例1:
a = 2;
var a ;
console.log(a);	//2
示例2:
console.log(b); //undefined
var b = 2;
示例3:
var c;
console.log(c);	//undefined
c = 2;
示例4:
foo();
function foo(){
	console.log(d);	//undefined
	var d = 2;
}
示例5:
bar();	//TypeError
var bar = function too(){
	// ....
}
示例6:
aoo();	//TypeError
boo();	//ReferenceError
var aoo = function boo(){
	// ...
}
示例7:
function foo(){
	console.log(1);
}
foo();	//1
foo = function(){
	console.log(2);
};
示例8:
foo();	//3
function foo(){
	console.log(1);
}
var foo = function(){
	console.log(2);	
};
function foo(){
	console.log(3);
}
示例9:
foo();	//b
var a = true;
if(a){
	function foo(){ console.log("a"); }
}else{
	function foo(){ console.log("b"); }
}

注意:這個行為並不可靠,在JavaScript未來的版本中有可能發生改變,因此應該儘可能避免在塊內部宣告函式。

總結:
1. var a = 2;其中var a在編譯階段,a=2在執行階段;
2. 無論作用域中的宣告(變數和函式)出現在什麼地方,都將在程式碼本身執行前首先進行處理;
3. 宣告本身會被提升,而包括函式表示式的賦值在內的賦值操作並不會提升;
4. 函式會首先被提升,然後才是變數,重複的var(變數)宣告會被忽略掉;
5. 後面的函式宣告可以覆蓋前面的。

PS:
1. RHS查詢在所有巢狀的作用域中遍尋不到所需遍歷會丟擲ReferenceError。

2. RHS查詢到一個變數,但你嘗試對其不合理的操作(引用null或undefined型別中的屬性),會丟擲TypeError。