一个经典的闭包面试题

Shut up, show me the code!!!

function showBiBao() {
    for (var i = 0; i < 5; i++) {
      setTimeout( function timer() {
          console.log(i);
      }, 1000 );
    }
    console.log(i)
}
// 会输出什么
showBiBao()

会用到的两个知识点:

  • 闭包
  • setTimeout

提示:
这个代码是有bug的,怎么解决?

解决方法:

第一步:先找出bug原因
1.1:for循环5次,那么应该设定了5个定时器,这个没错
1.2:setTimeout等待for循环执行完成后立即调用定时器
1.3:setTimeout被放在了队列的数据结构中(for循环),等待上下文的代码运行后再执行定时器,此时运行定时器,变量i已经变成了5(此时5个定时器的i都是5),所以输出全是5

第二步:怎么解决?
2.1:需要把每个定时器访问的变量独立起来,改变i的作用域
2.1:可以用闭包实现这个目的:在for循环里写一个闭包
2.3:show code

function showListNumber() {
    for(var i = 0; i < 5; i++) {
        (function(i) {
            setTimeout(function timerr() {
                console.log(i)
            }, 1000)
        })(i)
    }
    console.log(i)
}
showListNumber()

第三步:还能怎么做?
3.1:改变i的作用域就可以消除bug
3.2:可以用let声明一个仅对当前{}(块作用域)内有效的变量。

function useLetChange() {
    for (let i = 0; i < 5; i++) {
      setTimeout( function timer() {
          console.log(i);
      }, 1000 );
    }
}

useLetChange()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容