我只想在1秒后打印出for循环中的值,但是当我在firebug中运行代码时,每次运行代码时都会打印出意外的值。不确定发生了什么。
for(var k=0; k<3; k++) {
setTimeout(function() { console.log(k); },1000);
}
我预计1秒后: 0 1 2
相反,我得到了这个: 3635 3
答案 0 :(得分:2)
您需要在函数中包含k
变量的副本,否则您的函数将引用k
变量,在该变量之外,函数执行时的值为3:
for(var k=0; k<3; k++) {
(function(k_copy) {
setTimeout(function() { console.log(k_copy); },1000);
})(k); // immediately execute
}
使用Function.prototype.bind替代方案:
for(var k=0; k<3; k++) {
setTimeout(function(k_copy) { console.log(k_copy); }.bind(null,k),1000);
}
答案 1 :(得分:1)
您看到的第一个整数是从setTimeout
返回的结果
它是您可以在.clearTimeout()
除此之外,你必须使用一个闭包来打印正确的值。
for(var k=0; k<3; k++) {
(function(k) {
setTimeout(function() {
console.log(k);
},1000);
})(k);
}
答案 2 :(得分:1)
您看到的四位数字是setTimeout
的返回值,这是numerical id,您可以在以后用它来取消计时器。
setTimeout
方法将其参数设置为稍后调用 ,并立即继续当前函数。所以你的代码很快完成了for循环,调用了setTimeout三次。完成该循环后,k
为3。
然后,一秒钟后,超时触发,并将k(3
)记录到控制台。
我相信你只看到3
输出一次的原因是setTimeout
只会为给定的函数设置一个超时。你传递了三次完全相同的功能。我没有在documentation中看到这种行为,因此它可能是实现定义的。
我怀疑你想要的是在一秒钟之后打印k
的三个不同值。要做到这一点,你实际上需要创建一个不同的变量,其值不会改变。您可以使用返回函数的额外函数来执行此操作:
var makefunc = function (k2) {
return function() { console.log(k2); };
}
for(var k=0; k<3; k++) {
setTimeout(makefunc(k),1000);
}
每次调用makefunc
时,它都会在此处创建一个新变量(名为k2
,但实际上,如果该变量名为k
),这也会起作用。该变量保持活跃状态,直到console.log
呼叫一秒钟后。
更简洁的写作方式:
for(var k=0; k<3; k++) {
setTimeout(function(k) { return function() { console.log(k); }; }(k), 1000);
}
答案 3 :(得分:1)
我建议在异步JavaScript上查找一些资源,因为理解这将有助于这种情况。 JavaScript是单线程的,在调用回调函数之前会等待。想一想:
理解这是JavaScript中的关键。正如其他人已经说过的那样,你需要将k的值传递给每个回调(闭包),以便在回调首次放入堆栈时访问该值。
(其他答案的代码完美无缺):
for(var k=0; k<3; k++) {
(function(k) {
setTimeout(function() {
console.log(k);
},1000);
})(k);
}
对于3635和3686标识符,这实际上是我刚才从其他答案中学到的新东西!谢谢!
答案 4 :(得分:0)
3635和3686是setTimeout函数的标识符,它们用于在必要时清除超时。要打印0,1,2,请使用下一个代码
for(var k=0; k<3; k++) {
(function(k){
setTimeout(function() { console.log(k); },1000);
})(k);
}