首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >解释Javascript中闭包的输出

解释Javascript中闭包的输出
EN

Stack Overflow用户
提问于 2017-01-25 19:26:11
回答 4查看 40关注 0票数 0

在下面的代码片段中,6被打印了5次。请解释一下这种输出行为。

对于每个i,我都会调用settimeout函数,因此console.log应该具有i的值。代码:

代码语言:javascript
运行
复制
for(var i = 1;i <= 5;i++) {
   setTimeout(function() {
      console.log("i:" +  i);
   },i*1000);
}

文书主任6 6 6

O/P预期为%1%2%3%4%5

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-01-25 19:37:02

即使超时0也会产生相同的结果,要理解这一点,你必须理解事件循环中的回调概念。理想情况下,回调只在堆栈为空的时候执行,js代码的执行是基于堆栈的,我指的是执行上下文,所以当你在这里说一个for循环时,它意味着第一个i被推入堆栈,所以现在堆栈处理这个变量,当它涉及到回调(setTimeout)时,它存储的增量值是一个事件循环。

在event-loop中运行块的唯一方法是当你的堆栈为空时,即当你的循环结束时,因为它是一个闭包函数,所以它保留了最后一个值,其中所有的日志都被打印出来了。

参见示例,您将看到1到6个外部回调,因为它在堆栈中执行,但只有在堆栈为空时才会进行回调。

如果您想更好地理解执行上下文,请转到loupe并复制、粘贴您的js代码以查看操作。

代码语言:javascript
运行
复制
for(var i = 1;i <= 5;i++)
    {
        console.log(i)
        setTimeout(function(){
                console.log("i:" +  i);
                     },0
               );

    }

票数 2
EN

Stack Overflow用户

发布于 2017-01-25 19:35:17

这是因为该函数在for循环的相同作用域中使用变量

在执行setTimeout函数时,作用域中的变量i已经更改了值,因此所有计时器都将打印循环的最后一个值

尝试将i值作为setTimeout的参数传递,以便立即对其求值,并且函数可以使用其自身作用域中的值,而不会有任何副作用

代码语言:javascript
运行
复制
for(var i = 1;i <= 5;i++)
    {
        setTimeout(function(a){
                console.log("i:" +  a);
                     },i*1000,i
               );

    }
票数 1
EN

Stack Overflow用户

发布于 2017-01-25 19:34:05

在js中,变量具有块/函数作用域,并且setTimeout异步工作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41850424

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档