寫作不易,轉載請注明出處,謝謝。
首先,上幾道我編寫的 js 題,作為分析的樣本。
請根據代碼,選擇正確的選項。
第一題
var a = 0;
function test(){
alert(a);
}
test();
A. 0
B. null
C. undefined
第二題
var a = 0;
function test(){
alert(a);
a = 100;
}
test();
A. 0
B. null
C. undefined
第三題
var a = 0;
function test(){
alert(a);
var a = 100;
}
test();
A. 0
B. 100
C. undefined
正確答案:
A , A , C
前兩題沒啥好說的,之前關于閉包的博文中已經講得很清楚了,函數 test 形成了自己的閉包,所以能夠訪問到全局作用域里面的變量 a 。
第三題可能有人會覺得有點奇怪,為啥是 undefined 的呢?雖然我在閉包內定義了 var a = 100 , 可是它分明是在 alert 語句的下面啊,所以不是應該先打印出全局作用域里的 a 嗎?
不要著急,我們來講一個故事吧,當你將這段代碼放進瀏覽器跑起來的那一個瞬間,到底發生了哪些有趣的事情。
當你刷新瀏覽器之后。。。
0.00000001 毫秒的時候
編譯器看到了這句話,
var a = 0;
編譯器 : ‘nice,發現一個活的 a 變量,我要把它丟到作用域中去囚禁它!
于是
0.00000002 毫秒的時候
編譯器 : nice,發現一個活的 test 變量,我擦,還是一個函數類型,作用域,又有新貨了!
作用域 : ‘可以呀,小伙子!’
于是:
編譯器順便把 test 函數給“扒”了,又發現里面有這么一句話:
var a = 100;
編譯器:小樣,別以為你躲在 test 函數的私有作用域里面我就找不到你了,全局作用域中的a和你沒關系,你也進去!
編譯器:嗯,沒找到什么變量定義了,好,我去休息啦。
0.00000003 毫秒的時候
js引擎:終于輪到我出場了。
var a = 0;
a(全局): js引擎大哥,給我吃飯吧 。。。
js引擎: 吵啥子吵,先給你個undefined,吃這個吧 。
于是:
a(全局):只要心中有夢想,undefined也是嚼勁十足!
js引擎: 等號右邊有一個 0 ,我把它給你吧。
a(全局):謝謝引擎大哥。
同樣的,test 變量 也吃上了飯。
a(局部) : 大哥,我別這么偏袒全局作用域啊,同樣是 a 變量,我也要吃飯啊!
js引擎:你在函數內部,我還沒執行函數呢,怎么給你吃飯呀,先給你個undefined吧。
a(局部) :可是我旁邊有一個100啊。
js引擎:我剛才不是說了嗎,我還沒執行你呢,別挑了,有個undefined啃啃也不錯了。
0.00000004 毫秒的時候
test();
js引擎:我要開始執行test函數了。
alert(a);
js引擎:作用域在嗎,我知道alert是一個內置函數,當我在執行它的時候,發現有一個a變量作為參數傳進去了,你見過它么?
作用域:有啊,就那個剛才還吵著要吃飯的家伙。
js引擎:哦,我想起來了,現在它估計還在啃undefined呢,行吧,你把它給我吧,alert方法點名要找他呢。
作用域:OK。
故事到這里就講完了,現在你應該明白為什么第三題的答案是undefined了吧。
附加題:
var a = 0;
function test(){
alert(a);
if(false){
var a = 100;
}
}
test();
A. 0
B. 100
C. undefined
別猶豫,大聲說出你的答案吧!
可以將答案寫在評論中哦!