2011-12-25 57 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

深嵌套函数没有被执行的差异。你没有返回执行。