Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么深层嵌套函数可以访问顶级变量?_Javascript_Closures - Fatal编程技术网

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

Javascript 为什么深层嵌套函数可以访问顶级变量?,javascript,closures,Javascript,Closures,我一直在读javascript,我发现闭包只能访问“包装”它的闭包,或者,你可以说它是直接父对象。现在我已经玩了一点,我看到即使是深嵌套函数也可以访问上面定义的变量 谁能解释一下吗?或者解释我完全错了什么 这是因为该链会进一步向上延伸到顶部上下文。 在本例中,这将是: window < runNums < anonymous < anonymous < anonymous window

我一直在读javascript,我发现闭包只能访问“包装”它的闭包,或者,你可以说它是直接父对象。现在我已经玩了一点,我看到即使是深嵌套函数也可以访问上面定义的变量

谁能解释一下吗?或者解释我完全错了什么


这是因为该链会进一步向上延伸到顶部上下文。
在本例中,这将是:

window < runNums < anonymous < anonymous < anonymous
window

这些变量中的任何一个变量都将在最后一个匿名函数中可用。在runNums中,只有runNums或window中的变量可用。在第一个匿名函数中,只有它的变量和那些存在于runNums或window中的变量可用,等等。

在不深入细节的情况下,
闭包
从技术上描述了一个类似数组的变量
,该变量位于javascript引擎处理的所谓激活对象中。ActivationObject包含由
var
声明的变量、函数声明和形式参数

这意味着,只要调用一个新函数(-context),就会在内部创建一个新的激活对象。该对象是新的
执行上下文的一部分,TypicCall EC如下所示:

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


注意:上面的行为没有完全描述,这需要几页文本。它还描述了ECMAScript 3 262规范。ES5中的工作原理稍有不同,但仍然是一样的

这里的只是窗口对象

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

试试这个,看看有什么不同

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

深层嵌套函数尚未执行。您没有返回它们来执行。

是的,闭包“关闭”了它在所有父级可以看到的变量。一个封闭的函数可以看到所有的变量??如果您确实从某个地方读取,你可能想停止阅读那些有明显错误信息的材料:P当然它可以访问所有父级。另请参见。我希望它能以这种方式工作,因为这也是scope在各种语言中嵌套函数/过程的一般工作方式。如果闭包也不能以这种方式工作,那就很混乱了。或者,用两个词来回答你的问题:为什么不?
var someFunc = new runNums();
someFunc();