我试图解决为什么下面的代码在包含括号时导致堆栈溢出的原因,但是当它们被省略时则不会.
我将函数本身作为setTimeout的参数调用,它在没有parantheses的情况下工作,但当我添加它们时当然会失败.在函数之后添加()是我的直觉.只希望有人可以为我解决这个问题.parans什么时候可选而不是?
情况1:
var a = 1;
function foo() {
a++;
document.write(a);
setTimeout(foo(), 2000)
}?
// RangeError: Maximum call stack size exceeded
Run Code Online (Sandbox Code Playgroud)
案例2:
var a = 1;
function foo() {
a++;
document.write(a);
setTimeout(foo, 2000)
}?
// parens are omitted on foo function and it works.
Run Code Online (Sandbox Code Playgroud)
Way*_*ett 11
这个问题通常首先被提及setTimeout,但我认为重要的是要指出这里的行为不是特定于该功能.您只需要了解括号的作用以及将它们放下的含义.
假设以下功能:
function foo() {
return 5;
}
Run Code Online (Sandbox Code Playgroud)
考虑以下两个变量声明/赋值:
var one = foo();
var two = foo;
Run Code Online (Sandbox Code Playgroud)
这些变量有什么价值?
在第一种情况下,我们正在执行该foo函数并将其返回值 - 数字5- 分配给one.在第二种情况下,我们分配foo自己 - 更确切地说,是对foo- 的引用two.该功能永远不会执行.
有了这些知识和理解,setTimeout期望作为第一个参数对函数的引用,显然为什么你的第一个案例失败,但第二个案例有效.
当然,你正在执行的函数是对自身的递归调用这一事实加剧了你的问题.这将永远运行 - 对于永远的某些定义 - 因为没有基本情况来终止递归.
通过写作
foo()
Run Code Online (Sandbox Code Playgroud)
那个时候你真的在叫foo.当然然后再次调用foo()...直到你stackoverflow.
在案例2中,你有效地将"引用"传递给foo,说"在2s中运行".实际上并没有调用foo().
因此,当您真正想要调用它时,请使用parens.不是你想要引用它.
| 归档时间: |
|
| 查看次数: |
1614 次 |
| 最近记录: |