美文网首页
最常见的面试题之for循环

最常见的面试题之for循环

作者: MrOldK | 来源:发表于2018-09-08 20:58 被阅读124次

    小伙伴们去面试,可能常常会问到以下这个题。

       for(var i=0;i<10;i++){
            setTimeout(function(){
                console.log(i)
            },100)
        }//输出:10个10
    

    这道题考察的重点是var声明变量的作用域问题。如果对种问题不熟的同学,最后说出的答案可能就是1,2,3,4,5,6,7,8,9,10
    看到过有博客上写这个跟 setTimeout也有关系, setTimeout是个异步任务,会被浏览器加入到任务队列,等待100ms后执行。for循环是同步任务,主线程会执行完同步任务以后,再去任务队列执行异步任务的回调函数。当然这种说法也没错, 但这不是核心问题。如果用let来声明呢??

    //变形一
       for(var i=0;i<10;i++){
            setTimeout(function(){
                console.log(i)
            },100)
        }//输出:1,2,3,4,5,6,7,8,9,10
    

    这就看出来,仅仅只改变变量的声明关键字,问题就会迎刃而解。所以setTimeout的存在与否并没有影响。
    在for循环语句中,用var声明的变量会上升到全局,之所以会这样,就是因为ES5语法中没有,没有块级作用域,而ES6中新增了块级作用域。 块作用域由 { } 包括,if语句和for语句里面的{ }也属于块作用域。
    所以let声明的变量会绑定到当前作用域,每一次循环,都是一个块级作用域的生成,所以只在本次循环内有效。
    那如果还是用var关键字声明变量,怎样实现let的效果呢??

    //变形二  
        for(var i=0;i<10;i++){
            (function(){
                var index = i;
                setTimeout(function(){
                    console.log(index)
                })
            })()
        }//输出:1,2,3,4,5,6,7,8,9,10
    

    通过用自执行函数的形式,将每一次循环的i,赋值给一个变量index,用index来保存,形成最终的闭包。也就是将i绑定到当前局部作用域,成为setTimeout回调函数的私有变量,不会被浏览器回收。也可以这样:

    //变形三 
        for(var i=0;i<10;i++){
            (function(index){
                setTimeout(function(){
                    console.log(index)
                })
            })(i)
        }//输出:1,2,3,4,5,6,7,8,9,10
    
    //变形四 
     function timeout(index){
        setTimeout(function(){
            console.log(index)
        })
     }
    for(var i=0;i<10;i++){
        timeout(i)
    }//输出:1,2,3,4,5,6,7,8,9,10
    

    其实变形二和变形三,变形四的道理是一样的,这里不过多叙述。
    以上个人简介,如有错误请指正。

    相关文章

      网友评论

          本文标题:最常见的面试题之for循环

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