为了账号安全,请及时绑定邮箱和手机立即绑定

setTimeout第一个参数是立即执行函数,看不懂了

setTimeout第一个参数是立即执行函数,看不懂了

慕工程0101907 2018-11-14 18:43:28
setTimeout第一个参数是立即执行函数,看不懂了for (var i = 0; i < 5; i++) {  setTimeout((function(i) {    console.log(i);  })(i), i * 1000);}虽然结果是立即输出0,1,2,3,4,但是不知道为啥
查看完整描述

1 回答

?
慕侠2389804

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.


查看完整回答
反对 回复 2018-12-15
  • 1 回答
  • 0 关注
  • 1233 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号