为什么深层嵌套函数可以访问顶级变量?

时间:2011-12-25 11:43:34

标签: javascript closures

我一直在做一些javascript阅读,并且我已经收集到一个闭包只能访问闭包“包装”它,或者,你可能会说它是直接的父。现在我已经玩了一点,我在this jsfiddle中看到即使是深层嵌套函数也可以访问定义的变量。

有人可以解释一下吗?或者解释一下我完全错了什么?

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

var someFunc = runNums();
someFunc(); 

4 个答案:

答案 0 :(得分:6)

在不深入细节的情况下,closure在技术上描述了从javascript引擎处理的所谓激活对象中的array like variable。 ActivationObject包含由var函数声明形式参数声明的变量。

这意味着,无论何时调用新函数(-context),都会在内部创建新的激活对象。该对象是新Execution Context的一部分,典型的EC看起来像:

  • 此上下文变量
  • 激活对象
  • [[范围]]

这里有趣的部分是[[Scope]]。该变量包含所有父父上下文的所有激活对象,并在调用EC时填充。所以现在,当一个函数想要访问一个变量时,名称解析过程首先查看它自己的激活对象,如果找不到任何内容,搜索将继续在“范围链”中进行,这只是一个索引搜索通过我们的[[Scope]]变量(这也是父上下文的数组)。这就是为什么我们也在ECMA- / Javascript中谈论很多关于“词汇范围”的内容。

注意:上述行为未完全描述,需要多页文本。它还描述了ECMAscript3 262规范。在ES5中,事情有点不同,但它仍然是一样的

答案 1 :(得分:4)

这是因为链条进一步延伸到顶部环境 在示例中,那将是:

window < runNums < anonymous < anonymous < anonymous

生活在其中任何一个中的变量将在最后一个匿名函数中提供。在runNums中,只有生活在runNums或window中的变量才可用。在第一个匿名函数中,只有它的变量和生活在runNums或窗口中的变量才可用,等等。

答案 2 :(得分:0)

这个只是这里的Window对象。

此处 runNums 是一个全局函数, runNums()等于 window.runNums()。所以这个窗口 this.topVar window.topVar 。显然它可以从任何地方访问。

试试这个,看看差异

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

答案 3 :(得分:0)

尚未执行深层嵌套函数。你没有将它们退回执行。