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

js执行上下文和任务队列问题

js执行上下文和任务队列问题

慕粉1469491289 2017-04-20 17:04:07
为什么打印出来的结果是这样的,最近在看执行上下文----栈------任务队列,一脸懵逼啊
查看完整描述

4 回答

已采纳
?
会飞的四脚蛇

TA贡献5条经验 获得超3个赞

//img1.sycdn.imooc.com//58f993260001830d07260460.jpg

如果想要依次次输出,0,1,2,3,4,5,用不用闭包都可以实现。

主要有两点要注意: 1. 作用域。

                               2. setTimeout的运行机制。


查看完整回答
1 反对 回复 2017-04-21
  • feno
    feno
    请问如果不使用闭包,如何达到依次输出0 1 2 3 4 5的效果
  • 会飞的四脚蛇
    会飞的四脚蛇
    for(var i=0;i<=5;i++){ setTimeout((function () { console.log(i); })(i),i*1000); //这样写没什么意义,不是闭包.外层自执行函数去掉,直接console.log(i)也可以 } var timer =setTimeout(function () { console.log("1秒打印出来"); },0); console.log("other action"); 依次输出:0,1,2,3,4,5,other action,1秒打印出来;
  • feno
    feno
    setTimeout((function () { console.log(i); })(i),i*1000); 这一行代码报错了,WAService.js:5 Uncaught TypeError: setTimetout expects a function as first argument but got .(…);闭包的意义在于保存了循环中临时产生的i的数值
点击展开后面3
?
高jay

TA贡献96条经验 获得超122个赞

这是作用域问题,js没有块级作用域。i是全全局变量他在循环完成后就是最后一次的值。
查看完整回答
1 反对 回复 2017-04-20
?
winner4265975

TA贡献19条经验 获得超17个赞



关键问题是js引擎是单线程的,所以所以并不存在真正意义上的异步,它所谓的异步就是不同步。setTimeout是js的异步表现之一,js所有异步都会入队。任务队列只有在主线程执行完了才会去执行任务队列,所以你这个先输出主线程‘other actions’,再输出i==0时的那个6,然后输出‘1秒后打印出来’(这可不是1秒而是你主程结束处理完队列中排在他前面的任务后立马打印所以时间不确定例如你other actions底下写一个死循环那个6和它就永远不会打印),最后每隔1s输出那5个6,如果你把i*1000改为0就是同时输出那6个6然后输出‘1秒后打印出来’这是因为队列和栈不一样它是先进先出。

栈是一种数据结构表现为后进先出!

关于执行上下文

1.只有唯一的一个全局上下文window

2.函数的执行上下文的个数没有限制

3.每次某个函数被调用,就会有个新的执行上下文为其创建,即使是调用的自身函数,也是如此。


查看完整回答
反对 回复 2017-04-23
?
ruibin

TA贡献358条经验 获得超213个赞

这个是闭包问题。你理解错了,这样写就好了


for (var i = 0; i < 4; i ++) {
   setTimeout((function(i) {
       return function() {
           console.log(i);
       }
   })(i), i * 1000)
}

查看完整回答
反对 回复 2017-04-20
  • 4 回答
  • 1 关注
  • 2184 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信