假设以下方法(只是好奇,我希望在js
中失败)
foo(0);
function foo(i){
if(i<1000){
setTimeout(function(){foo(i+1);}, 1000);
}
alert('I am foo');
}
因此,如果我得到它,它应该在1000秒后提醒大约1000 I am foo
秒
那么浏览器是否会将i
保持在一个大堆栈中呢?它应该是太多我认为还是我错了?
答案 0 :(得分:2)
是的,您将使用此代码提醒1000“foo”消息。
但是,浏览器不会受到i
变量数量的影响。 i
是foo
的局部变量,因此只要foo
执行,它就会保留。每次setTimeout回调完成执行时,i
和整个函数的足迹都有资格进行浏览器的垃圾收集(这将在适当的时候发生)。
原因是由于使用了setTimeout,因此这里没有保留的内存调用堆栈。 setTimeout对foo
的返回值没有任何作用,因此内存中没有指针保持该函数及其变量环境不被收集。
答案 1 :(得分:1)
您的调用堆栈将如下所示,因为您的代码通过它的循环:
main() [local foo]
main() -> foo [local i = 0]
main()
(empty)
setTimeout()
setTimeout() -> foo [local i = 1]
setTimeout()
(empty)
setTimeout()
setTimeout() -> foo [local i = 2]
setTimeout()
(empty)
一遍又一遍,直到i
等于1000
。
这种方式就是这样,因为setTimeout是一个等待n
时间的浏览器api,然后将回调插入回调队列。然后回调将被事件循环拾取并在callstack为空时执行。
所以,不,你没有任何使用堆栈或变量或任何你担心的东西超载浏览器的危险。您的callstack将保持较小,因为每次执行foo
时,它都会触发setTimeout并返回。 i
将保留在内存中,直到执行setTimeout的回调,此时将在执行i
创建的范围内创建新的foo
。新的i
将保留在内存中,直到下一个setTimeout执行,on和on。
这是一段可能有助于解释其工作原理的视频。 http://www.youtube.com/watch?v=8aGhZQkoFbQ
答案 2 :(得分:0)
1000 i
对于浏览器来说并不是一个非常大的尺寸。
此外,同时不会超过2 i
s(甚至可能只有一个),每个函数每秒执行一次。
此代码不会加载1000次调用以1秒的间隔触发,这将链接调用,防止堆栈膨胀。
答案 3 :(得分:0)
首先在javascript中没有“int”你必须说var i
。它就是宣言的类型。如果你想获得有关堆栈的信息。您可以使用调试控制台。然后导航到调用堆栈。它是一个很好的功能,你也有一个很好的概述。我更喜欢Chromes调试器。你可以按F12