a = 2;
var a;
console.log(a);
// 打印結(jié)果
// 2
console.log(a);
var a = 2;
// 打印結(jié)果
// undefined
兩段代碼:
- 代碼1輸出結(jié)果『超出預期』昂芜,通常會認為結(jié)果為:undefined哄辣,但實際結(jié)果卻是2;
- 代碼2輸出結(jié)果『符合預期』正歼;
Why 霹购?
這就涉及到JS引擎:編譯與執(zhí)行了:
- 編譯階段:會將變量聲明提升至所在作用域最前面;
- 執(zhí)行階段:賦值或調(diào)用所處位置不變朋腋;
注:
- 后面會講到函數(shù)的提升齐疙;
- 變量提升是早期開發(fā)人員的一個bug,后來也未修正旭咽;
我們來分析上面兩段代碼:
- 編譯階段贞奋,將變量聲明提升至所在作用域最前面(這里是全局作用域):
var a;
- 執(zhí)行階段,賦值or函數(shù)調(diào)用所處位置不變:
a = 2;
console.log(a);
--------------------------------------------------------
| 所以穷绵,實際編譯后的代碼形式如下:
--------------------------------------------------------
var a;
a = 2;
console.log(a); // 2
- 編譯階段轿塔,將變量聲明提升至所在作用域最前面(這里是全局作用域):
var a;
- 執(zhí)行階段,賦值or函數(shù)調(diào)用所處位置不變:
console.log(a);
a = 2;
--------------------------------------------------------
| 所以仲墨,實際編譯后的代碼形式如下:
--------------------------------------------------------
var a;
console.log(a); // undefined
a = 2;
/**
* 這里有個細節(jié):
* 代碼中是 var a = 2
* 但是在編譯階段勾缭,將其拆成了兩條語句:
* var a;
* a = 2;
*/
小測試(寫出編譯后的代碼):
function foo () {
console.log(a);
var a = 2;
}
--------------------------------------------------------
| 所以,實際編譯后的代碼形式如下:
--------------------------------------------------------
function foo () {
var a;
console.log(a); // undefined
a = 2;
}