歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

一道阿裡巴巴Web前端面試題拓展

第二第三個問題由第一個拓展而來,先看問題吧:

第一問:

var a = 6; 
setTimeout(function () {     
    alert(a);    //輸出66 
    a = 666;}, 
1000); 
a = 66; 

第二問:

var a = 6; 
setTimeout(function () {     
    var a = 666; 
    alert(a);      // 輸出666, 
}, 1000); 
a = 66; 

第三問:

var a = 6; 
setTimeout(function () {     
    alert(a);      // 輸出undefined, 
    var a=666; 
}, 1000); 
a = 66; 

這三個問題涉及到了setTimeout的工作原理,執行環境與作用域還有函數的創建與調用。

首先先說一下setTimeout(function(),ms)函數,現在在我們的js文件中有這麼一段代碼:setTimeout( a() , 5000 );。

在執行流執行到setTimeout代碼時,並不會原地踏步地等待執行完畢後再向下執行,而是會告訴浏覽器,我這段代碼要等待5秒之後再執行,然後立即向下執行接下來的代碼。

現在可以先解決第一問了。

首先定義了一個局部變量a,並且a=6 。然後執行流遇到了setTimeout(),告訴浏覽器,我1秒之後再執行這段代碼,此時a仍然為6。然後跳過setTimeout()中的代碼繼續向下執行,就碰到了a=66,將a賦值為66 。一秒過去了之後,浏覽器開始調用setTimeout()函數中的匿名函數,遇到了alert(a),在此之前匿名函數中並沒有創造局部變量a,所以隨著作用域鏈由內向外搜尋有沒有變量a。當搜尋到外部函數的作用域時,發現a已經被賦值成了66,則返回結果,最終彈出窗口顯示66。

第二問中,由於在setTimeout()的匿名函數中擁有了一個局部變量a,所以最後alert(a)輸出的是666,這一個沒什麼可說的。

至於第三問的解答,涉及到了一個函數的創建與執行的區別,讓我想起了C和C++中的函數創建執行部分(更多的是本人的猜想,未經求證),在進入setTimeout()函數之後,我們得先創建一個函數,然後才能執行它,在創建函數的時候,會搜尋函數內部是否有變量創建出來了。所以,當執行流遇到alert(a)的時候,開始搜尋當前環境下有沒有a變量,最終發現了一個a變量,但是在未執行var a=666之前,a並沒有被賦值,所以alert(a)的最終結果為undefined。

關於更多的執行環境與作用域的知識,在《JavaScript高級編程》一書中有比較詳盡的說明。

JavaScript高級編程 PDF高清版 下載地址: http://www.linuxidc.com/Linux/2014-12/110884.htm

這三個問題涉及到了setTimeout的工作原理,執行環境與作用域還有函數的創建與調用。

Copyright © Linux教程網 All Rights Reserved