閉包、定時(shí)器

什么是閉包? 有什么作用

可以先看下一段代碼

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

其中innerFn()為內(nèi)部函數(shù),在outerFn()外無(wú)法直接調(diào)用。但是可以讓outerFn()返回innerFn。這樣可以在outerFn()外間接調(diào)用函數(shù)innerFn()。

  • 即使離開(kāi)函數(shù)作用域的情況下仍然能夠通過(guò)引用調(diào)用內(nèi)部函數(shù)的事實(shí),意味著只要存在調(diào)用內(nèi)部函數(shù)的可能,JavaScript就需要保留被引用的函數(shù)。而且JavaScript運(yùn)行時(shí)需要跟蹤引用這個(gè)內(nèi)部函數(shù)的所有變量,直到最后一個(gè)變量廢棄,JavaScript的垃圾收集器才能釋放相應(yīng)的內(nèi)存空間)。
  • 閉包是指有權(quán)限訪問(wèn)另一個(gè)函數(shù)作用域的變量的函數(shù)??衫斫鉃閯?chuàng)建閉包的常見(jiàn)方式就是在一個(gè)函數(shù)內(nèi)創(chuàng)建另一個(gè)函數(shù)。

setTimeout 0 有什么作用

  • setTimeout是一個(gè)延時(shí)函數(shù),當(dāng)設(shè)定延遲的時(shí)間為0時(shí),會(huì)使setTimeout內(nèi)部的函數(shù)在所有要執(zhí)行的js語(yǔ)句執(zhí)行完成之后再執(zhí)行。

代碼題目

下面的代碼輸出多少?修改代碼讓fnArri 輸出 i。使用兩種以上的方法

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

方法1.1 利用函數(shù)參數(shù)傳遞使得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;在此函數(shù)內(nèi)未找到i,返回上一級(jí)尋找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;在此函數(shù)內(nèi)未找到i,返回上一級(jí)尋找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利用函數(shù)參數(shù)傳遞使得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、創(chuàng)建函數(shù)(立即執(zhí)行函數(shù))
2、使 num =i ;(使用var num =i;或者用函數(shù)參數(shù)傳遞)
3、return num;

使用閉包封裝一個(gè)汽車對(duì)象,可以通過(guò)如下方式獲取汽車狀態(tài)

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

寫(xiě)一個(gè)函數(shù)使用setTimeout模擬setInterval的功能

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

注意要點(diǎn):需要將func()寫(xiě)在setTimeout()內(nèi)部

寫(xiě)一個(gè)函數(shù),計(jì)算setTimeout平均[備注:新加]最小時(shí)間粒度

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

下面這段代碼輸出結(jié)果是? 為什么?

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是一個(gè)延時(shí)函數(shù),當(dāng)設(shè)定延遲的時(shí)間為0時(shí),會(huì)使setTimeout內(nèi)部的函數(shù)在所有要執(zhí)行的js語(yǔ)句執(zhí)行完成之后再執(zhí)行。

下面這段代碼輸出結(jié)果是? 為什么?

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

到while(flag){}卡主,因?yàn)閟etTimeout導(dǎo)致flag =false處于最后,當(dāng)執(zhí)行到while(flag){}時(shí),由于flag為true導(dǎo)致停在此代碼處。

下面這段代碼輸出?如何輸出delayer: 0, delayer:1...(使用閉包來(lái)實(shí)現(xiàn))

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);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 問(wèn)題 一、什么是閉包? 有什么作用? 閉包閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。在javascript中,只有函...
    婷樓沐熙閱讀 655評(píng)論 0 0
  • 問(wèn)答 1.什么是閉包? 有什么作用? 閉包 簡(jiǎn)而言之 就是讓函數(shù)外部可以訪問(wèn)函數(shù)內(nèi)的局部變量,就是將函數(shù)內(nèi)部和函數(shù)...
    我是小韓閱讀 364評(píng)論 1 0
  • 1.什么是閉包? 有什么作用 閉包指有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域的變量的函數(shù)。創(chuàng)建閉包的常見(jiàn)方式 是 在一個(gè)函數(shù)...
    JunVincetHuo閱讀 1,513評(píng)論 0 2
  • 本教程版權(quán)歸小圓和饑人谷所有,轉(zhuǎn)載須說(shuō)明來(lái)源 問(wèn)題 什么是閉包? 有什么作用閉包(closure)是指有權(quán)訪問(wèn)另一...
    饑人谷__小圓閱讀 534評(píng)論 0 0
  • 什么是閉包? 有什么作用閉包:函數(shù)對(duì)象可以通過(guò)作用域鏈相互關(guān)聯(lián),函數(shù)體內(nèi)部的變量可以保存在函數(shù)的作用域內(nèi)。 上述代...
    coolheadedY閱讀 812評(píng)論 0 0

友情鏈接更多精彩內(nèi)容