abd*_*ziq 0 javascript recursion
在JavaScript中,当函数调用自身时,它是如何在作用域链中解析的?
function myFunc(){
myFunc()
}
Run Code Online (Sandbox Code Playgroud)
我知道这是糟糕的代码,并将永远运行.
使用函数声明(如上所述),在函数内,函数的名称在范围内.它被添加到声明它的执行上下文的变量绑定对象中.这一点在第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 节和其他内容涉及该决议,但它们真的很难.:-)