zoukankan      html  css  js  c++  java
  • 当setTimeout遇到闭包

    1:

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

    或者比较正规的写法(code 加上引号):

    function myTest(){
        for(var i=0; i< 5; i++){
            setTimeout("console.log(" + i + ")", 0);
        }
    }
    myTest();

    控制台输出结果为 0,1,2,3,4

     2:

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

    控制台输出结果为 5,5,5,5,5

     虽然setTimeout(code, 0)为立即执行,但由于javascript为单线程,所以还需等待循环结束后才会执行setTimeout

     由于阻塞,在循环中产生的setTimeout事件会被放在执行队列中进行等待。

     1中放入执行队列的是:console.log(i) ,结果为 0,1,2,3,4

     2中放入执行队列的是:function(){ console.log(i); }, 结果为 5,5,5,5,5 为什么呢

     原因:2放入队列的是匿名函数,等到匿名函数执行的时候,变量i已经累加到5了

     有时,需要执行的代码不仅仅一句console.log(i)这么简单,那么2中要怎么才能做到输出 0,1,2,3,4

     这里就讲到闭包:

     内部函数可以使用外部的变量。

     既然i为外部变量已经不可控,那就对i下手吧

     修改如下:

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

     每次循环先把立即(function(v){...})(i);把i作为参数传入闭包,就不会对变量造成污染。

  • 相关阅读:
    结对作业
    黄金分割点(第五周 c语言版)
    小程序(第四周)
    读程序作业(第三周)
    vs2013的安装及测试(第三周)
    学习进度条(第6周)
    努力爬的蜗牛
    学习日记1
    团队作业(七)
    团队作业(六)
  • 原文地址:https://www.cnblogs.com/rubekid/p/4035671.html
Copyright © 2011-2022 走看看