首先,上幾道我編寫的 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 毫秒的時候
![你可曾見過如此簡單粗暴的JavaScript解說-js腳本運行機制](http://p2.ttnews.xyz/loading.gif)
Paste_Image.png
編譯器看到了這句話,
var a = 0;
編譯器 : ‘nice,發現一個活的 a 變量,我要把它丟到作用域中去囚禁它!
於是
![你可曾見過如此簡單粗暴的JavaScript解說-js腳本運行機制](http://p2.ttnews.xyz/loading.gif)
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
別猶豫,大聲說出你的答案吧!
可以將答案寫在評論中哦!
閱讀更多 程序猿的內心獨白 的文章
關鍵字: 美好,一直在身邊 瀏覽器 JavaScript