美文网首页
一个经典的闭包面试题

一个经典的闭包面试题

作者: 本一和他的朋友们 | 来源:发表于2018-10-28 17:40 被阅读12次

    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()
    

    相关文章

      网友评论

          本文标题:一个经典的闭包面试题

          本文链接:https://www.haomeiwen.com/subject/lthmtqtx.html