Js 閉包据德、定時器

問題

什么是閉包? 有什么作用

閉包可以用來讀取函數(shù)內(nèi)部的變量鳄乏。

function f1() {
  var n = 999;
  function f2() {
    console.log(n);
  }
  return f2;
}

var result = f1();
result(); //999

由于作用域鏈表跷车,外部是無法讀取到函數(shù)內(nèi)部的變量的。所以如果想要得到函數(shù)內(nèi)部的變量橱野,可以在函數(shù)體內(nèi)部再定義一個函數(shù)朽缴,這個用這個函數(shù)返回所需要的變量。

function create_counter(initial) { 
    var x = initial || 0; 
    return { inc: function () { 
    x += 1; 
    return x; 
    } 
}}

var c1 = create_counter();
c1.inc(); // 1
c1.inc(); // 2
c1.inc(); // 3

var c2 = create_counter(10);
c2.inc(); // 11
c2.inc(); // 12
c2.inc(); // 13
  • 上面例子中水援,c1,c2引用的外部函數(shù)的x密强,是獨立的兩個值,封閉的包裝蜗元。
  • 閉包可以理解為是攜帶狀態(tài)的函數(shù)或渤,并且它的狀態(tài)可以完全對外隱藏起來。

setTimeout 0 有什么作用

setTimeout(f, 0) ; 將第二個參數(shù)設為 0奕扣,作用是讓 f 在現(xiàn)有的任務(腳本的同步任務和“消息隊列”指定的任務)一結束就立刻執(zhí)行薪鹦。也就是說,setTimeout(f, 0)的作用是惯豆,盡可能早地執(zhí)行指定的任務池磁,而并不是會立刻就執(zhí)行這個任務。

  • 可以用于調(diào)整事件的發(fā)生順序楷兽;
  • 將一些消耗性能的任務地熄,分成小塊放到setTimeout(f, 0)中,可以減輕性能壓力芯杀。

代碼題

下面的代碼輸出多少端考?修改代碼讓fnArr[i]()輸出 i。使用兩種以上的方法

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

這段代碼輸出10揭厚。上段循環(huán)中却特,將一個函數(shù),依次寫進一個數(shù)組中棋弥,而這個函數(shù)不是立即執(zhí)行的核偿,通過fnArr[]()調(diào)用,才進行執(zhí)行顽染。所以當循環(huán)結束后漾岳,此時i的數(shù)值已經(jīng)變化為10,當調(diào)用fnArr[3](),實際上執(zhí)行的是return i ; 粉寞,而此時的 i 就是 10尼荆。

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

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

function car(){
  var speed = 0;
  return {
    setSpeed:function(val){
      speed = val;
      return speed;
    },
    getSpeed:function(){
      console.log(speed);
      return speed;
    },
    accelerate:function(){
      speed += 10;
    },
    decelerate:function(){
      speed -= 10;
      if (speed < 0){
        speed = 0;
      } 
    },
    getStatus:function(){
      if(speed!==0){
        console.log('running');
        return 'running';
      }
      else {
        console.log('stoped');
        return 'stoped';
      }
    }
  };
}

var Car = car();

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;  //undefined;

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

var i = 0;
function interval(){
  setTimeout(function(){
    console.log(i++);
    interval();
  },1000);
}
interval();

寫一個函數(shù)唧垦,計算setTimeout最小時間粒度

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

下面這段代碼輸出結果是? 為什么?

var a = 1;
setTimeout(function(){
    a = 2;
    console.log(a);//3執(zhí)行
}, 0);
var a ;
console.log(a);  //1執(zhí)行
a = 3;
console.log(a);//2執(zhí)行
//1  3  2
  • setTimeout(func,0) 會將任務在下一個Event Loop之前執(zhí)行捅儒,所以這里的function被移到了最后進行執(zhí)行。

下面這段代碼輸出結果是? 為什么?

var flag = true;
setTimeout(function(){
    flag = false;
},0);//理論上不會執(zhí)行
while(flag){}
console.log(flag);//理論上不會執(zhí)行
  • setTimeout將function移到下一個Event Loop之前執(zhí)行,但是while將這個阻斷了巧还,陷入了無限循環(huán)鞭莽。所以flag不能被賦值成false。這也說明程序的運行是單線程的麸祷。

下面這段代碼輸出澎怒?如何輸出delayer: 0, delayer:1...(使用閉包來實現(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);
}

本教程版權歸 張宇 及 饑人谷 所有,轉載請標明出處阶牍。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末喷面,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子走孽,更是在濱河造成了極大的恐慌惧辈,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件磕瓷,死亡現(xiàn)場離奇詭異盒齿,居然都是意外死亡,警方通過查閱死者的電腦和手機生宛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門县昂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來肮柜,“玉大人陷舅,你說我怎么就攤上這事∩蠖矗” “怎么了莱睁?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長芒澜。 經(jīng)常有香客問我仰剿,道長,這世上最難降的妖魔是什么痴晦? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任南吮,我火速辦了婚禮,結果婚禮上誊酌,老公的妹妹穿的比我還像新娘部凑。我一直安慰自己,他們只是感情好碧浊,可當我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布涂邀。 她就那樣靜靜地躺著,像睡著了一般箱锐。 火紅的嫁衣襯著肌膚如雪比勉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天,我揣著相機與錄音浩聋,去河邊找鬼观蜗。 笑死,一個胖子當著我的面吹牛衣洁,可吹牛的內(nèi)容都是我干的嫂便。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼闸与,長吁一口氣:“原來是場噩夢啊……” “哼毙替!你這毒婦竟也來了?” 一聲冷哼從身側響起践樱,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤厂画,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后拷邢,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體袱院,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年瞭稼,在試婚紗的時候發(fā)現(xiàn)自己被綠了忽洛。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡环肘,死狀恐怖欲虚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情悔雹,我是刑警寧澤复哆,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站腌零,受9級特大地震影響梯找,放射性物質發(fā)生泄漏。R本人自食惡果不足惜益涧,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一锈锤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧闲询,春花似錦久免、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至寄狼,卻和暖如春丁寄,著一層夾襖步出監(jiān)牢的瞬間氨淌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工伊磺, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留盛正,地道東北人。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓屑埋,卻偏偏與公主長得像豪筝,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子摘能,可洞房花燭夜當晚...
    茶點故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 什么是閉包? 有什么作用閉包:函數(shù)對象可以通過作用域鏈相互關聯(lián)团搞,函數(shù)體內(nèi)部的變量可以保存在函數(shù)的作用域內(nèi)严望。 上述代...
    coolheadedY閱讀 727評論 0 0
  • 一像吻、問題 (一)、什么是閉包? 有什么作用 閉包是指能夠訪問自由變量的函數(shù) (變量在本地使用复隆,但在閉包中定義)拨匆。換...
    該帳號已被查封_才怪閱讀 397評論 0 1
  • 1: 下面的代碼輸出多少?修改代碼讓 fnArri 輸出 i挽拂。使用 兩種以上的方法 輸出結果為10惭每,因為retur...
    DeeJay_Y閱讀 356評論 0 0
  • 1.什么是閉包? 有什么作用 函數(shù)的作用域scope取決于聲明時洪鸭,而非調(diào)用時。普通函數(shù)執(zhí)行后函數(shù)體及內(nèi)部變量會被垃...
    泰格_R閱讀 612評論 0 1
  • 孩子的童年是一張?zhí)畛鋱D冊仑扑,早有絢麗的框架,只是需要和他們一起去填充置鼻。 放假的那天镇饮,晶晶問我:暑假打算帶孩子去哪啊箕母?...
    左清水閱讀 522評論 2 3