只学JS。 在我看来,函数setTimeout代码区应该像正常一样工作,但它不是,exp:
var result = 0;
(function (i){
if(i > 0){
result = result + i;
i = i - 1;
setTimeout("arguments.callee(" + i + ")",100);//arguments.callee(i);
}
else if(i == 0)
return;
}(10));
alert(result);
我希望它警报55而不是10,如果删除setTimeout,它会很好。 有谁知道为什么?
答案 0 :(得分:0)
因为setTimeout
是异步,简单来说意味着它计划稍后执行。 JS不会等待它(不会停止该行的代码),而是运行后续代码。
因此,当您稍后设置它时,代码会继续在之外您的“超时循环”并进入警报。在此期间,循环仅执行一个循环,result
仅添加了10。
你能做什么:
arguments.callee
is deprecated。您可以命名您的IIFE并将其超时称为答案 1 :(得分:0)
尝试
var result = 0;
(function (i, callback) {
if (i > 0) {
result = result + i;
i = i - 1;
var callee = arguments.callee;
setTimeout(function () {
callee(i, callback)
}, 100);
} else if (i == 0) {
callback();
}
}(10, function () {
alert(result);
}));
演示:Fiddle
为什么?
您的方法存在多个问题
setTimeout
时,它将在全局范围内执行,即arguments.callee
将引用与您期望的不同的对象。答案 2 :(得分:0)
鉴于:
考虑在IIFE中声明功能(根据我的想法进行调整 - 在10次迭代后显示结果为10的警报):
var result = 0;
(function (i){
function foo(j) {
if(j > 0){
++result;
setTimeout(function(){foo(--j)},100);
} else {
alert('Result: ' + result);
}
}
foo(i);
}(10));
请注意,不需要 else 块(除非您想要返回undefined
以外的其他内容)。
哦,请注意,在ES5和支持它的其他浏览器(不是IE< 9)中,您可以在调用setTimeout时传递参数:
setTimeout(foo, 100, --j);
所以你保存了一个额外的功能对象。