javascript中的递归函数 - 如何在范围链中重新调用

abd*_*ziq 0 javascript recursion

在JavaScript中,当函数调用自身时,它是如何在作用域链中解析的?

function myFunc(){
    myFunc()
}
Run Code Online (Sandbox Code Playgroud)

我知道这是糟糕的代码,并将永远运行.

T.J*_*der 5

使用函数声明(如上所述),在函数内,函数的名称在范围内.它被添加到声明它的执行上下文的变量绑定对象中.这一点在第10.4.3 第10.5 中的turgid散文中有所涉及.规范.

例如,考虑一下:

function foo() {

    function bar() {
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

我的问题是如何解决它

您可以将JavaScript范围视为Matryoshka:一个在另一个内部.当JavaScript引擎遇到标识符时(如bar上面的示例所示),它会查看最里面的"范围"(变量绑定对象)以查看它是否具有该标识符的条目.如果是,它就会使用它.如果没有,它会查看包含范围以查看是否具有它,依此类推,等等,直到我们达到全局范围.如果在"范围链"中的任何一点都没有解析标识符,并且如果你试图从中读取一个值,那么会导致一个ReferenceError.(如果你试图在它上面设置一个值,它会创建一个隐含的全局 - 请参阅我的文章"隐含全局的恐怖"  - 或者导致ReferenceError 如果你处于严格的模式.)

第10.3.1节,第10.2.2.1 和其他内容涉及该决议,但它们真的很难.:-)