Javascript中的范围链和在全局范围内调用嵌套函数
Posted
技术标签:
【中文标题】Javascript中的范围链和在全局范围内调用嵌套函数【英文标题】:Scope chain in Javascript and calling nested function within the global scope 【发布时间】:2015-11-25 19:55:08 【问题描述】:这是我想要启发的示例(实际上不起作用的东西)。
var myVar = 2;
function a()
var myVar = 2;
function b()
console.log(myVar);
;
a();
b();
这会在控制台输出:Uncaught ReferenceError: b is not defined。
如您所见,我有一个名为 a 的函数和一个名为 b 的嵌套函数。
起初我以为我可以在 a 之外调用 b 并让它正常工作。 我认为这会起作用,因为一开始我调用了 a 函数。
通过这样做,我想到了 a 函数 将被放入执行堆栈中,并且在其创建阶段,将设置内部定义的 b 函数在记忆中。
因为这是在内存中,所以我想我可以在函数之外执行它。这显然行不通。
所以我的结论是 b 函数 确实在 a 函数 的创建阶段被设置到内存中,但是一旦 a 函数 具有执行完毕,一旦从执行栈中弹出,b函数同时从内存中弹出。
因此在全局范围内调用它(我的意思是 b 函数)是不可能的。
我说对了吗?
【问题讨论】:
javascript 有 lexical scope 并且也适用于函数。 【参考方案1】:您通过谈论执行堆栈、创建阶段等使事情变得不必要地复杂化。
解释很简单:您不能调用b
,因为规范说b
超出了您尝试调用它的站点的范围。就是这样,故事结束。
如果转换为 php,您的示例实际上会起作用,这让我认为这也许就是您的灵感来源。但是 JS 和 PHP 是不同的语言,PHP 对待嵌套函数的(IMO 荒谬的)方式并没有转移。
【讨论】:
是的,你是对的,我试图在反思中走得太深......我知道我不能在 Javascript 中做到这一点,但我试图完全理解为什么。涉及的所有机制。但实际上它更简单。解释是名为“b”的函数位于名为“a”的函数内。然后当我们尝试从全局范围调用它时它会失败,因为全局执行环境会寻找函数 b,但在全局执行上下文的创建阶段从未将它添加到其变量环境中......总结一下,它们与您告诉我的范围不同。谢谢【参考方案2】:如果你想在a
之外调用b
,你需要在a
之外创建对它的引用:
var myVar = 2;
function a()
var myVar = 2;
function b()
console.log(myVar);
return b;
;
var b = a();
b();
但这不会导致b
打印全局myVar
。它仍然可以访问a
的闭包范围内的myVar
。
【讨论】:
以上是关于Javascript中的范围链和在全局范围内调用嵌套函数的主要内容,如果未能解决你的问题,请参考以下文章