function test() {
for(var i=0; i<10; i++) {
setTimeout(function(){
(function (m) {
console.log(m);
})(i)
}, 500)
}
}
test();
PHPz2017-04-11 12:07:17
直接在setTimeout()
里用即时执行封装下回调就行了,你封包在setTimeout()
的里边跟没封区别不大:
function test() {
for(var i=1; i<11; i++) {
setTimeout((function(){
console.log(i);
})(), 500)
}
}
test();
补充:
如果想做成间隔500ms一次console.log,那我觉得不如直接写成:
var i = 1;
var ii = setInterval(function(){
if (i<11) {
console.log(i);
i++;
} else {
clearInterval(ii);
}
}, 500);
高洛峰2017-04-11 12:07:17
题主之所以会出现此问题,完全是由于没有理解闭包
es5之前js是没有块级作用域这个说法的
可以通过()()来模拟块级作用域
for(var i = 0; i < 10; i++) {
setTimeout((function(){
console.log(i)
})(),500)
}
// 0 1 2 3 4 5 6 7 8 9
es6通过let命令,声明变量只在书写的let命令代码块内有效
所以 @radius 写的就复杂了
for(let i=0; i<10; i++) {
setTimeout(function(){
console.log(i);
}, 500)
}
// 0 1 2 3 4 5 6 7 8 9
阮一峰es6块级作用域
迷茫2017-04-11 12:07:17
function test() {
for(var i=0; i<10; i++) {
(function(i){
setTimeout(function(){
console.log(i);
},500);
})(i)
}
}
test();
这个是循环0-9 1-10你自己改
PHPz2017-04-11 12:07:17
function test() {
for(var i = 1 ;i<=10;i++){
(function(i){
setTimeout(function(){
console.log(i)
},500)
})(i);
}
}
test();
大家讲道理2017-04-11 12:07:17
function test(){
for(var i = 0 ;i<10 ;i++){
setTimeout((function(m){
return function(){ console.log(m)}
})(i),500);
}
}
test();
阿神2017-04-11 12:07:17
function test() {
for(var i=1; i<=10; i++) {
setTimeout((function(m){
return function () {
console.log(m);
}
})(i), 500 * i)
}
}
test();
大家讲道理2017-04-11 12:07:17
function count() {
var arr = [];
for (var i=1; i<=3; i++) {
arr.push(function () {
return i * i;
});
}
return arr;
}
var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];
在上面的例子中,每次循环,都创建了一个新的函数,然后,把创建的3个函数都添加到一个Array中返回了。
你可能认为调用f1(),f2()和f3()结果应该是1,4,9,但实际结果是:
f1(); // 16
f2(); // 16
f3(); // 16
返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
廖雪峰教程:闭包
阿神2017-04-11 12:07:17
function test() {
for(let i=0; i<10; i++) {
setTimeout(function(){
(function (m) {
console.log(m);
})(i)
}, 500)
}
}
test();
只把var改成let就行了
迷茫2017-04-11 12:07:17
es2016 or typescript:
async function test() {
var i = 0;
for (i = 0; i < 10; i++) {
await new Promise(resolve => setTimeout(resolve, 500));
console.log(i);
}
}
test();