0

在 JavaScript 中,当一个函数调用自身时,它如何在作用域链中得到解析?

function myFunc(){
    myFunc()
}

我知道这是糟糕的代码,并且会永远运行。

4

1 回答 1

5

使用函数声明(如您上面的),在函数内,函数的名称在范围内。它被添加到声明它的执行上下文的变量绑定对象中。这在第 10.4.3节和第 10.5节的冗长散文中有所介绍。的规范。

例如,考虑:

function foo() {

    function bar() {
    }
}

当您调用foo时,它会为调用创建一个执行上下文。该上下文有一个与之关联的变量绑定对象(我跳过了一些细节),您可以松散地将其视为该调用的“范围”。在执行其中的任何分步代码之前发生的一件事foo是,其中的所有函数声明都被评估,并且这些函数的名称被添加到变量绑定对象中以调用foo. (这也是foo存储 的参数名称和局部变量的地方。)由于bar 关闭了该上下文,它可以访问绑定,包括为其命名的绑定。

当最初输入全局代码时,同样的事情(有效地)发生,使用全局上下文而不是调用foo.

我的问题是它是如何解决的

你可以把 JavaScript 作用域想象成俄罗斯套娃:一个在另一个里面。当 JavaScript 引擎遇到一个标识符时(如bar我上面的示例),它会查看最里面的“范围”(变量绑定对象)以查看它是否具有该标识符的条目。如果是,它会使用它。如果没有,它会查看包含范围以查看是否具有它,依此类推,直到我们到达全局范围。如果标识符在这个“作用域链”中的任何一点都没有被解析,并且如果你试图从中读取一个值,那会导致一个ReferenceError. (如果你想给它设置一个值,它要么创建一个隐式全局——参见我的文章隐式全局的恐怖 ——要么导致一个ReferenceError如果您处于严格模式。)

10.3.110.2.2.1和其他部分涵盖了此解决方案,但它们确实很难实施。:-)

于 2013-10-01T08:58:51.257 回答