javascript中的递归函数 - 如何在范围链中解析

时间:2013-10-01 08:53:27

标签: javascript recursion

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

function myFunc(){
    myFunc()
}

我知道这是不好的代码,会永远运行。

1 个答案:

答案 0 :(得分:5)

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

例如,考虑一下:

function foo() {

    function bar() {
    }
}

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

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

  

我的问题是如何解决

您可以将JavaScript范围视为Matryoshka:一个在另一个内部。当JavaScript引擎遇到一个标识符(如上例中的bar)时,它会查看最里面的“范围”(变量绑定对象)以查看它是否有该标识符的条目。如果是,它就会使用它。如果没有,它会查看包含范围以查看 it 是否包含它,依此类推,等等,直到我们达到全局范围。如果标识符未在此“范围链”中的任何位置解析,并且您尝试从中读取值,则会导致ReferenceError。 (如果您尝试设置一个值,它会创建一个隐含的全局 - 请参阅我的文章The Horror of Implicit Globals - 如果您严格要求,则会导致ReferenceError模式。)

此解决方案由Section 10.3.110.2.2.1和其他人涵盖,但他们真的很难。 : - )