javascript - 有关setTimeout的问题

查看:161
本文介绍了javascript - 有关setTimeout的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

下面这段代码:

for(var j = 0;j < 10;j++) {
  setTimeout(function(){console.log(j)},1000*j);
}

结果是:立马输出一个10,然后每隔一秒输出一个10。

不是很理解,这是很容易可以看出输出10是因为Js异步任务的关系,但是按理说for循环执行完之后,j已经是10,那里面的那个1000*j不就应该是10秒,最终结果也有应该是程序执行后,10秒过后一次性打印10个10才对,为什么会隔一秒输出一次,难道1000*j这里面的j其实是被记录了的(0、1、2、3...9)?。

是不是说,for每循环一次,j就加1,每个循环中被挂起的setTimeout是记录了每次j的值的,只是在最后10个setTimeout运行的时候,j已经是10了,这会儿那个function(){console.log(j)}只能拿到j的值是10?

还有,如果把第一个参数的function去了,就会变成瞬间打印,没有延迟,不管是1000还是1000*j都一样,setTimeout好像被忽略了:

请问上面两个问题分别是什么原因?

解决方案

第一个问题,第一个循环时,是

setTimeout(function(){console.log('a')},1000*1);

这是对setTimeout的一次调用,结果就是把function在1000*1毫秒后扔到任务队列去。
循环第二轮继续,这个时候是在1000*2毫秒后扔到任务队列去,这里的j跟function里用变量j是不一样的,function是后面可以调用时发现自己里面并没有j的声明才去外层作用域找变量j,此时j=10;可每次循环中调用setTimeout其实就是一个function的普通调用过程,正如:

function normal(n){
    console.log(n);
}

for(var i=0;i<10;i++){
    normal(i*1000);
}

这样对比例子,能明白吧?

第二个问题呢,跟上一个问题我觉得是类似的。

setTimeout(console.log(j),1000*j);

正常来说,setTimeout的第一个参数要求是function,当然也可以是别的,具体看 https://developer.mozilla.org...

但这里不涉及到这setTimeout的定义范畴了。

其实换个写法:

function normal(n){
    console.log('i am called');
}

for(var i=0;i<10;i++){
    normal(console.log(i));
}

当在调用normal方法的时候,首先参数里面是一个函数的执行,注意是执行,而不是什么匿名函数的声明之类的。
所以第一步是先执行掉参数里面的'执行函数',得到函数执行的值,然后作为参数传入到方法中去。

这样说,题主能理解不?

这篇关于javascript - 有关setTimeout的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆