闭包、定时器

作者: Nicklzy | 来源:发表于2016-08-24 17:16 被阅读26次

    什么是闭包? 有什么作用

    可以先看下一段代码

    function outerFn() {
        console.log("Outer function");
        function innerFn() {
            console.log("Inner function");
        }
        return innerFn;
    }
    var fnRef = outerFn();
    fnRef();
    

    其中innerFn()为内部函数,在outerFn()外无法直接调用。但是可以让outerFn()返回innerFn。这样可以在outerFn()外间接调用函数innerFn()。

    • 即使离开函数作用域的情况下仍然能够通过引用调用内部函数的事实,意味着只要存在调用内部函数的可能,JavaScript就需要保留被引用的函数。而且JavaScript运行时需要跟踪引用这个内部函数的所有变量,直到最后一个变量废弃,JavaScript的垃圾收集器才能释放相应的内存空间)。
    • 闭包是指有权限访问另一个函数作用域的变量的函数。可理解为创建闭包的常见方式就是在一个函数内创建另一个函数。

    setTimeout 0 有什么作用

    • setTimeout是一个延时函数,当设定延迟的时间为0时,会使setTimeout内部的函数在所有要执行的js语句执行完成之后再执行。

    代码题目

    下面的代码输出多少?修改代码让fnArri 输出 i。使用两种以上的方法

    var fnArr = [];
    for (var i = 0; i < 10; i ++) {
        fnArr[i] =  function(){
            return i;
        };
    }
    console.log( fnArr[3]() );  //
    

    方法1.1 利用函数参数传递使得num=i

    var fnArr = [];
    for (var i = 0; i < 10; i ++) {
        (function(num){
            fnArr[i] =  function(){
            return num;
        };
        })(i)
    }
    console.log( fnArr[3]() );  //
    

    方法1.2 直接用命名定义 var num =1;在此函数内未找到i,返回上一级寻找i

    var fnArr = [];
    for (var i = 0; i < 10; i ++) {
        (function(){
            var num = i;
            fnArr[i] =  function(){
            return num;
        };
        })()
    }
    console.log( fnArr[3]() );  //
    

    方法2.1直接用命名定义 var num =1;在此函数内未找到i,返回上一级寻找i

    var fnArr = [];
    for (var i = 0; i < 10; i ++) {
        fnArr[i] =  (function(){
            var num =i;
            return function(){
              return num;
            }
        })();
    }
    console.log( fnArr[3]() );  //
    

    方法2.2利用函数参数传递使得num=i

    var fnArr = [];
    for (var i = 0; i < 10; i ++) {
        fnArr[i] =  (function(num){
            return function(){
              return num;
            }
        })(i);
    }
    console.log( fnArr[3]() );  //
    

    四种方法的核心:
    1、创建函数(立即执行函数)
    2、使 num =i ;(使用var num =i;或者用函数参数传递)
    3、return num;

    使用闭包封装一个汽车对象,可以通过如下方式获取汽车状态

    var Car = //todo;
    Car.setSpeed(30);
    Car.getSpeed(); //30
    Car.accelerate();
    Car.getSpeed(); //40;
    Car.decelerate();
    Car.decelerate();
    Car.getSpeed(); //20
    Car.getStatus(); // 'running';
    Car.decelerate(); 
    Car.decelerate();
    Car.getStatus();  //'stop';
    //Car.speed;  //error
    

    代码如下

    function getCar(){
      var i =0;
      function setSpeed(k){
         i = k;
      }
      function accelerate(){
         i +=10;
      } 
      function decelerate(){
         i -=10;
      }
      function getSpeed(){
        return i;
      }    
      function getStatus(){
        if(i>0){
          return 'running'
        }else{
          return 'stop'
        }
      }
      return {
        setSpeed: setSpeed,
        accelerate: accelerate,
        decelerate: decelerate,
        getSpeed: getSpeed,
        getStatus: getStatus
      }
    }
    var Car = getCar();
    

    写一个函数使用setTimeout模拟setInterval的功能

    function interval(func,time){  
      return setTimeout(function(){
        func();
        interval(func,time);
      },time);
    }
    

    注意要点:需要将func()写在setTimeout()内部

    写一个函数,计算setTimeout平均[备注:新加]最小时间粒度

    function mini(){
      var i = 0;
      var start = Date.now();
      var clock = setTimeout(function(){
        i++;
        if(i === 1000){
          clearTimeout(clock);
          var end = Date.now();
          console.log((end-start)/i);
        }
        clock =setTimeout(arguments.callee,0)
      },0)
    }
    mini()
    

    下面这段代码输出结果是? 为什么?

    var a = 1;
    setTimeout(function(){
        a = 2;
        console.log(a);
    }, 0);
    var a ;
    console.log(a);
    a = 3;
    console.log(a);
    //1,3,2
    //setTimeout是一个延时函数,当设定延迟的时间为0时,会使setTimeout内部的函数在所有要执行的js语句执行完成之后再执行。
    

    下面这段代码输出结果是? 为什么?

    var flag = true;
    setTimeout(function(){
        flag = false;
    },0)
    while(flag){}
    console.log(flag);
    

    到while(flag){}卡主,因为setTimeout导致flag =false处于最后,当执行到while(flag){}时,由于flag为true导致停在此代码处。

    下面这段代码输出?如何输出delayer: 0, delayer:1...(使用闭包来实现)

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

    代码如下

    for(var i=0;i<5;i++){
        (function(num){
            setTimeout(function(){
             console.log('delayer:' + num );
              }, 0);  
        })(i)
        console.log(i);
    }

    相关文章

      网友评论

        本文标题:闭包、定时器

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