【javascript】关于for语句中settimeout的代码理解

for (var i = 0; i < 10; i++) {
    setTimeout(() => {
        console.log(i)
    }, i * 1000)
}//打印输出10个10

为什么打印输出10个10?

javascript是单线程语言

 在浏览器中一个页面永远只有一个线程在执行js脚本代码(在不主动开启新线程的情况下)。

javascript是单线程语言,但是代码解析却十分的快速,不会发生解析阻塞

javascript是异步执行的,通过事件循环(Event Loop)的方式实现。

js的运行环境,运行环境主要有三种:

全局环境(JS代码加载完毕后,进入代码预编译即进入全局环境)
函数环境(函数调用执行时,进入该函数环境,不同的函数则函数环境不同)
eval(不建议使用,会有安全,性能等问题)
每进入一个不同的运行环境都会创建一个相应的执行上下文(Execution Context),
那么在一段JS程序中一般都会创建多个执行上下文,js引擎会以栈的方式对这些执行上下文进行处理,
形成函数调用栈(call stack),栈底永远是全局执行上下文(Global Execution Context),栈顶则永远是当前执行上下文。

所以打印10个10的原因可以用堆栈来解释,setTimeout是在到了指定时间的时候就把事件推到任务队列中,此时的var是作用于函数全局,而主线程执行栈早已经将for循环执行完毕,此时的i为10,再执行setTimeout的事件,则会打印出10个10。
PS:部分笔记摘自:
js引擎的执行1
js引擎的执行2

如何解决这个问题:

  • es6中的let
for (let i = 0; i < 10; i++) {
    setTimeout(() => {
        console.log(i)
    }, i * 1000)
}

因为let与var的作用域范围不同,let会对for产生作用域,而var则是全局。

  • 闭包
for (var i = 0; i < 10; i++) {
    void function (i) {
        setTimeout(() => {
            console.log(i)
        }, i * 1000)
    }(i)
}

限定var的作用范围

  • setoutTime的第三个参数
for (var i = 0; i < 10; i++) {
    setTimeout((j) => {
        console.log(j)
    }, i * 1000, i)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值