2011-12-25 33 views
3

我一直在做一些JavaScript閱讀,並且我已經知道閉包只能訪問閉包「包裝」它,或者,你可能會說它是直接父項。現在我玩了一下,我在this jsfiddle中看到,即使深層嵌套函數也可以訪問定義好的變量。爲什麼深層嵌套函數可以訪問頂層變量?

任何人都可以解釋一下嗎?或者解釋我完全錯了什麼?

http://jsfiddle.net/tPQ4s/
function runNums() { 
    this.topVar = 'blah'; 
    return function(){ 
     (function() {      
      (function() { 
       console.log(topVar); 
      })(); 
     })(); 
    } 
} 

var someFunc = runNums(); 
someFunc(); 
+0

是的,閉包「關閉」它在所有父級可以看到的變量。 – Max 2011-12-25 11:48:22

+0

一個封閉的函數可以看到所有的方式嗎? – MeLight 2011-12-25 11:51:39

+0

如果你真的從某個地方閱讀過,你可能想停止閱讀有明顯錯誤信息的材料:P當然,它可以訪問所有父母級別。 – Esailija 2011-12-25 11:55:17

回答

4

這是因爲鏈進一步延伸到頂部上下文。
在這個例子中,這將是:

window < runNums < anonymous < anonymous < anonymous 

變量住在任何這些將在最後的匿名函數可用。在runNums中,只有處於runNums或window的變量纔可用。在第一個匿名函數,只是它的變量和那些生活在runNums或窗口將可等

6

沒有去太深入的細節,一個closure技術上描述了這種所謂的激活對象是內array like variable從JavaScript引擎處理。一個ActivationObject包含變量聲明var,函數聲明形式參數

這意味着,無論何時調用新函數(-context),都會在內部創建一個新的激活對象。這個對象是新Execution Context的一部分,一個。典型EC的樣子:

  • 這種情況下可變
  • 激活對象
  • [適用範圍]

這裏的有趣的部分是[[Scope]]。該變量包含全部激活對象全部父上下文,並在調用EC時填充。所以現在,當一個函數想要訪問一個變量時,名稱解析過程首先查看它自己的激活對象,如果沒有發現任何東西,則搜索繼續進行「範圍鏈」,這只是一個索引搜索通過我們的[範圍]]變量(它也是父上下文的數組)。這就是爲什麼我們在ECMA-/Javascript中也講了很多關於「詞法範圍」的問題。

注意:上述行爲沒有完全描述,這將需要幾頁的文本。它還描述了ECMAscript3 262規範。事情在ES5中有點不同,但它仍然是一樣的東西

0

這個不過是這裏的Window對象。

這裏runNums是全局函數和runNums()等於window.runNums()。所以窗口this.topVarwindow.topVar。顯然它可以從任何地方訪問。

試試這個,看看

var someFunc = new runNums(); 
someFunc(); 
0

深嵌套函數沒有被執行的差異。你沒有返回執行。

相關問題