a = 2;
var a;
console.log(a);
// 打印結(jié)果
// 2
console.log(a);
var a = 2;
// 打印結(jié)果
// undefined
兩段代碼:
- 代碼1輸出結(jié)果『超出預(yù)期』,通常會(huì)認(rèn)為結(jié)果為:undefined,但實(shí)際結(jié)果卻是2;
- 代碼2輸出結(jié)果『符合預(yù)期』;
Why ?
這就涉及到JS引擎:編譯與執(zhí)行了:
- 編譯階段:會(huì)將變量聲明提升至所在作用域最前面;
- 執(zhí)行階段:賦值或調(diào)用所處位置不變;
注:
- 后面會(huì)講到函數(shù)的提升;
- 變量提升是早期開(kāi)發(fā)人員的一個(gè)bug,后來(lái)也未修正;
我們來(lái)分析上面兩段代碼:
- 編譯階段,將變量聲明提升至所在作用域最前面(這里是全局作用域):
var a;
- 執(zhí)行階段,賦值or函數(shù)調(diào)用所處位置不變:
a = 2;
console.log(a);
--------------------------------------------------------
| 所以,實(shí)際編譯后的代碼形式如下:
--------------------------------------------------------
var a;
a = 2;
console.log(a); // 2
- 編譯階段,將變量聲明提升至所在作用域最前面(這里是全局作用域):
var a;
- 執(zhí)行階段,賦值or函數(shù)調(diào)用所處位置不變:
console.log(a);
a = 2;
--------------------------------------------------------
| 所以,實(shí)際編譯后的代碼形式如下:
--------------------------------------------------------
var a;
console.log(a); // undefined
a = 2;
/**
* 這里有個(gè)細(xì)節(jié):
* 代碼中是 var a = 2
* 但是在編譯階段,將其拆成了兩條語(yǔ)句:
* var a;
* a = 2;
*/
小測(cè)試(寫(xiě)出編譯后的代碼):
function foo () {
console.log(a);
var a = 2;
}
--------------------------------------------------------
| 所以,實(shí)際編譯后的代碼形式如下:
--------------------------------------------------------
function foo () {
var a;
console.log(a); // undefined
a = 2;
}