03.14 你可曾見過如此簡單粗暴的JavaScript解說-js腳本運行機制

首先,上幾道我編寫的 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腳本運行機制

Paste_Image.png

編譯器看到了這句話,

var a = 0;

編譯器 : ‘nice,發現一個活的 a 變量,我要把它丟到作用域中去囚禁它!

於是

你可曾見過如此簡單粗暴的JavaScript解說-js腳本運行機制

0.00000002 毫秒的時候

編譯器 : nice,發現一個活的 test 變量,我擦,還是一個函數類型,作用域,又有新貨了!

作用域 : ‘可以呀,小夥子!’

於是:

你可曾見過如此簡單粗暴的JavaScript解說-js腳本運行機制

編譯器順便把 test 函數給“扒”了,又發現裡面有這麼一句話:

var a = 100;

編譯器:小樣,別以為你躲在 test 函數的私有作用域裡面我就找不到你了,全局作用域中的a和你沒關係,你也進去!

你可曾見過如此簡單粗暴的JavaScript解說-js腳本運行機制

編譯器:嗯,沒找到什麼變量定義了,好,我去休息啦。

0.00000003 毫秒的時候

js引擎:終於輪到我出場了。

你可曾見過如此簡單粗暴的JavaScript解說-js腳本運行機制

var a = 0;

a(全局): js引擎大哥,給我吃飯吧 。。。

js引擎: 吵啥子吵,先給你個undefined,吃這個吧 。

於是:

你可曾見過如此簡單粗暴的JavaScript解說-js腳本運行機制

a(全局):只要心中有夢想,undefined也是嚼勁十足!

js引擎: 等號右邊有一個 0 ,我把它給你吧。

a(全局):謝謝引擎大哥。

你可曾見過如此簡單粗暴的JavaScript解說-js腳本運行機制

同樣的,test 變量 也吃上了飯。

你可曾見過如此簡單粗暴的JavaScript解說-js腳本運行機制

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

別猶豫,大聲說出你的答案吧!

可以將答案寫在評論中哦!


分享到:


相關文章: