1 回答

TA贡献1719条经验 获得超6个赞
这样其实是一下子全部打印出来的。。。不是每隔一秒打印出来。。建议这样写。。
for (var i = 0; i < 5; i++) {
setTimeout((function(i) {
return function() {
console.log(i);
}
})(i), i * 1000);
}
我来解释一下这个为什么可以获取到0、1、2、3、4.
网上关于JS预解释的文章也不少,在进入执行上下文阶段的时候函数并不会执行,简单来说就是当你声明这个函数的时候,只要不调用就不会执行,上下文里面只会保存着这个函数的引用,可以看做这个函数保存在内存中,只有到调用的时候函数才会执行,我说说自己的理解,有不对的地方请指出来。
如果没有立即执行函数:
你在for循环里面实际上相当于定义了5个定时器,但是js是单线程,这五个函数会被放到队列里面等待执行,举个不一定恰当的例子,你就把这五个函数function() {console.log(i);}当成字符串保存到内存中,一直没什么动静,等到这五个函数调用执行的时候(就是setTimeout的第二个参数的时间到了的时候),才会开始执行这个函数,因为函数里面有个i,这个时候会通过作用域链来查找这个i,最后在外面的作用域里面查找到了i,但是这个时候for循环已经执行结束了,i已经变成4了,所以会打印出5个4.
如果有立即执行函数(比如我上面写的那个):
你在for循环里面实际上相当于定义了5个定时器,但是js是单线程,这五个函数会被放到队列里面等待执行。
(function(i) {
return function() { console.log(i); }})(i)
但是由于外面是立即执行函数,所以会立即就执行了,并且把i传了进去,等到这五个函数执行的时候,向上查找i,正好在这个立即调用函数的作用域里面查找到了i,所以会打印出0、1、2、3、4.
添加回答
举报