在 JavaScript 中,当一个函数调用自身时,它如何在作用域链中得到解析?
function myFunc(){
myFunc()
}
我知道这是糟糕的代码,并且会永远运行。
在 JavaScript 中,当一个函数调用自身时,它如何在作用域链中得到解析?
function myFunc(){
myFunc()
}
我知道这是糟糕的代码,并且会永远运行。
使用函数声明(如您上面的),在函数内,函数的名称在范围内。它被添加到声明它的执行上下文的变量绑定对象中。这在第 10.4.3节和第 10.5节的冗长散文中有所介绍。的规范。
例如,考虑:
function foo() {
function bar() {
}
}
当您调用foo
时,它会为调用创建一个执行上下文。该上下文有一个与之关联的变量绑定对象(我跳过了一些细节),您可以松散地将其视为该调用的“范围”。在执行其中的任何分步代码之前发生的一件事foo
是,其中的所有函数声明都被评估,并且这些函数的名称被添加到变量绑定对象中以调用foo
. (这也是foo
存储 的参数名称和局部变量的地方。)由于bar
关闭了该上下文,它可以访问绑定,包括为其命名的绑定。
当最初输入全局代码时,同样的事情(有效地)发生,使用全局上下文而不是调用foo
.
我的问题是它是如何解决的
你可以把 JavaScript 作用域想象成俄罗斯套娃:一个在另一个里面。当 JavaScript 引擎遇到一个标识符时(如bar
我上面的示例),它会查看最里面的“范围”(变量绑定对象)以查看它是否具有该标识符的条目。如果是,它会使用它。如果没有,它会查看包含范围以查看它是否具有它,依此类推,直到我们到达全局范围。如果标识符在这个“作用域链”中的任何一点都没有被解析,并且如果你试图从中读取一个值,那会导致一个ReferenceError
. (如果你想给它设置一个值,它要么创建一个隐式全局——参见我的文章隐式全局的恐怖 ——要么导致一个ReferenceError
如果您处于严格模式。)