我一直在做一些javascript阅读,并且我已经收集到一个闭包只能访问闭包“包装”它,或者,你可能会说它是直接的父。现在我已经玩了一点,我在this jsfiddle中看到即使是深层嵌套函数也可以访问定义的变量。
有人可以解释一下吗?或者解释一下我完全错了什么?
http://jsfiddle.net/tPQ4s/function runNums() {
this.topVar = 'blah';
return function(){
(function() {
(function() {
console.log(topVar);
})();
})();
}
}
var someFunc = runNums();
someFunc();
答案 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)
尚未执行深层嵌套函数。你没有将它们退回执行。