閉包、定時器

什么是閉包? 有什么作用

可以先看下一段代碼

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);
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 問題 一、什么是閉包? 有什么作用? 閉包閉包就是能夠讀取其他函數內部變量的函數。在javascript中,只有函...
    婷樓沐熙閱讀 601評論 0 0
  • 問答 1.什么是閉包? 有什么作用? 閉包 簡而言之 就是讓函數外部可以訪問函數內的局部變量,就是將函數內部和函數...
    我是小韓閱讀 317評論 1 0
  • 1.什么是閉包? 有什么作用 閉包指有權訪問另一個函數作用域的變量的函數。創建閉包的常見方式 是 在一個函數...
    JunVincetHuo閱讀 1,420評論 0 2
  • 本教程版權歸小圓和饑人谷所有,轉載須說明來源 問題 什么是閉包? 有什么作用閉包(closure)是指有權訪問另一...
    饑人谷__小圓閱讀 502評論 0 0
  • 什么是閉包? 有什么作用閉包:函數對象可以通過作用域鏈相互關聯,函數體內部的變量可以保存在函數的作用域內。 上述代...
    coolheadedY閱讀 754評論 0 0