在JavaScript中,当函数调用自身时,如何在作用域链中解析它?
function myFunc(){
myFunc()
}
我知道这是不好的代码,会永远运行。
答案 0 :(得分:5)
使用函数声明(如上所述),在函数内,函数的名称在范围内。它被添加到声明它的执行上下文的变量绑定对象中。这在Section 10.4.3和Section 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.1,10.2.2.1和其他人涵盖,但他们真的很难。 : - )