下面这段代码:
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在1000*1毫秒后扔到任务队列去。
循环第二轮继续,这个时候是在1000*2毫秒后扔到任务队列去,这里的j跟function里用变量j是不一样的,function是后面可以调用时发现自己里面并没有j的声明才去外层作用域找变量j,此时j=10;可每次循环中调用setTimeout其实就是一个function的普通调用过程,正如:
这样对比例子,能明白吧?
第二个问题呢,跟上一个问题我觉得是类似的。
正常来说,setTimeout的第一个参数要求是function,当然也可以是别的,具体看 https://developer.mozilla.org...
但这里不涉及到这setTimeout的定义范畴了。
其实换个写法:
当在调用normal方法的时候,首先参数里面是一个函数的执行,注意是执行,而不是什么匿名函数的声明之类的。
所以第一步是先执行掉参数里面的'执行函数',得到函数执行的值,然后作为参数传入到方法中去。
这样说,题主能理解不?