if (!("a" in window)) {
var a = 1; }
alert(a);
結果:undefined
分析: 首先,所有的全局變量都是window的屬性,語句 var a = 1;等價於window.a = 1;
第二,所有的變量聲明都在範圍作用域的頂部,如:
alert("a" in window);
var a;
相當於:
var a;
alert("a" in window);
這是因爲JavaScript引擎首先會掃墓所有的變量聲明,然後將這些變量聲明移動到頂部。
第三,你需要理解該題目的意思是,變量聲明被提前了,但變量賦值沒有,因爲這行代碼包括了變量聲明和變量賦值。
當變量聲明和賦值在一起用的時候,JavaScript引擎會自動將它分爲兩部以便將變量聲明提前,不將賦值的步驟提前是因爲他有可能影響代碼執行出不可預期的結果。
所以上面的代碼就相當於:
var a;
if (!("a" in window)) { 爲false
a = 1; }
alert(a); 所以爲undefined
例子2:
var num = 100;
function fn(){
var num = num + 1; //var num=window.num+1;正確,此時才外外面的全局變量num
return num;
}
falert(n());答案是NaN
因爲在函數體內部首先把var num提前,這樣在賦值的時候去的num + 1中的值是undefined,這樣進行運算後答案就是NaN,
記住我們找對象的時候是層級往上面找的,找不到才找外面的。
例子3:
var b = (function(){
function fn(){
return 1;
}
return fn();
function fn(){
return 2;
}
var fn;
fn = 3
})();
alert(b);答案是2,
因爲首先把var fn提前,然後函數體那樣子定義也是一種函數的聲明(需要提前),並且同名函數後面覆蓋前面的,所以就是var ,fn,fn,然後就renturn了,沒有走之後的fn=3,所以答案就是2
代碼等價於:
var b = (function(){
var fn;
function fn(){
return 2;
}
return fn();
fn = 3
})();
所以輸出2