JS閉包、定時器

  • 什么是閉包? 有什么作用
    • 閉包:函數(shù)對象可以通過作用域鏈相互關(guān)聯(lián),函數(shù)體內(nèi)部的變量可以保存在函數(shù)的作用域內(nèi)。
var scope = "global scope";
        function checkScope() {
            var scope = "local scope";
            function f() {
                return scope;
            }
            return f;
        }
        checkScope();//function f() { return scope; }
        checkScope()();//"local scope"
  • 上述代碼可以看出,閉包可以捕捉到函數(shù)的局部變量,并一直保存下來。在這種情況下,就可以在外部作用域下訪問到函數(shù)內(nèi)部的局部變量,就好像內(nèi)部變量綁定在了定義它的外部函數(shù)上,用于在外部訪問。
var inc = (function() {
            var a = 0;
            return function() {
                return a++;
            }
        })();
inc();
  • 用閉包方法寫立即執(zhí)行函數(shù),把這個函數(shù)的局部變量賦給inc變量,每次執(zhí)行inc()時都可以訪問到這個立即執(zhí)行函數(shù)內(nèi)部的局部變量
  • setTimeout 0 有什么作用
setTimeout(function(){}, 0)
  • setTimeou 0 表示以0毫秒的超時時間來調(diào)用setTimeout(),那么指定的函數(shù)不會立即執(zhí)行。反而會把這個函數(shù)放到隊列中,,等到前面處于等待狀態(tài)的事件處理程序全部執(zhí)行完成后,再立即調(diào)用這個函數(shù)。
  • 下面的代碼輸出多少?修改代碼讓fnArr[i]() 輸出 i。使用兩種以上的方法
var fnArr = [];
             for (var i = 0; i < 10; i ++) {
             fnArr[i] =  function(){
                  return i;
             };
        }
        console.log( fnArr[3]() );  //10
  • 方法:
 console.log("方法一");
         var fnArr = [];
             for (var i = 0; i < 10; i ++) {
             fnArr[i] =  (function() {
                var n = i;
                return function() {
                    return n;
                }
             })();
         }
        console.log( fnArr[3]() );
//------------------------------
        console.log("方法一改");
         var fnArr = [];
             for (var i = 0; i < 10; i ++) {
             fnArr[i] =  (function(n) {
                return function() {
                    return n;
                }
             })(i);
         }
        console.log( fnArr[3]() );
//------------------------------
        console.log("方法一改1");
         var fnArr = [];
         function fn(n) {
            return function() {
                return n;
            }
         }
             for (var i = 0; i < 10; i ++) {
             fnArr[i] = fn(i);
        }
        console.log( fnArr[3]() ); 
//------------------------------
        console.log("方法二");
        var fnArr = [];
             for (var i = 0; i < 10; i ++) {
             (function(n) {  
                fnArr[i] = function(){
                  return n;
                }
            })(i);
        }
        console.log( fnArr[3]() );
//------------------------------
        console.log("方法二改");
        var fnArr = [];
             for (var i = 0; i < 10; i ++) {
             (function() {
                var n = i;  
                fnArr[i] = function(){
                  return n;
                }
            })();
        }
        console.log( fnArr[3]() );
  • 使用閉包封裝一個汽車對象,可以通過如下方式獲取汽車狀態(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
        var Car = (function() {
            var status = "";
            var speed = 0;
            return {
                setSpeed: function(num) {  speed = num; },
                getSpeed: function() { return speed; },
                accelerate: function() {  speed += 10; },
                decelerate: function() {  speed -= 10; },
                getStatus: function() {
                    if (speed > 0) {
                        status = "runing";
                    } else {
                        status = "stop";
                    }
                    return status;
                }
            }
        })();//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
  • 寫一個函數(shù)使用setTimeout模擬setInterval的功能
        var a = 0;
        setTimeout(function(){
            console.log(++a);
            setTimeout(arguments.callee, 1000);
        }, 0);
        var a = 0;
        function intv() {
            setTimeout(function() {
                console.log(a++);
                intv();
            },1000);
        }
        intv();
  • 寫一個函數(shù),計算setTimeout最小時間粒度
        (function (){
            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);
        })();//5
  • 下面這段代碼輸出結(jié)果是? 為什么?
        var a = 1;
        setTimeout(function(){
            a = 2;
            console.log(a);
        }, 0);
        var a ;
        console.log(a);
        a = 3;
        console.log(a);
結(jié)果:
//1   setTmineout延遲到最后執(zhí)行a第一次執(zhí)行為1
//3   a被賦值為3。
//2   當(dāng)之前的事件程序全部執(zhí)行完成執(zhí)行setTimeout(),a被賦值為2并輸出。
當(dāng)setTimeout(func(), delay)中的delay設(shè)置為0時函數(shù)將會在前面的事件處理程序全部執(zhí)行完成后才立即執(zhí)行。
  • 下面這段代碼輸出結(jié)果是? 為什么?
        var flag = true;
        setTimeout(function(){
            flag = false;
        },0)
        while(flag){}
        console.log(flag);
  • 這段代碼將會使瀏覽器卡死,代碼中的setTimout()延遲為0,將會放在最后執(zhí)行。這時先執(zhí)行while循環(huán),變量flag為true不會改變,所以while循環(huán)會一直卡死在{}中。

  • 下面這段代碼輸出?如何輸出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++){
            setTimeout((function(n){
                return function() {
                     console.log('delayer:' + n );
                }
            })(i), 0);
            console.log(i);
        }

apply,call用法,實現(xiàn)bind
本博客版權(quán)歸 本人和饑人谷所有,轉(zhuǎn)載需說明來源

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • 1.什么是閉包? 有什么作用? 閉包是指有權(quán)訪問其他函數(shù)作用域中的變量的函數(shù)。 詳細(xì)解釋:就是在一個函數(shù)中,父函數(shù)...
    Sheldon_Yee閱讀 1,162評論 2 2
  • 閉包 定義「一個函數(shù)」+「訪問到的外部變量」= 閉包 作用創(chuàng)建內(nèi)部變量,既不能被外部隨意修改,又可以通過指定的函數(shù)...
    jrg_memo閱讀 529評論 0 0
  • 問答 什么是閉包? 有什么作用答:“官方”的解釋是:閉包是一個擁有許多變量和綁定了這些變量的環(huán)境的表達(dá)式(通常是一...
    饑人谷_桶飯閱讀 231評論 0 0
  • 好久沒寫種東西了,我怎么還是一想到就會心痛呢?可能是聽了許久的情歌,久到已經(jīng)抹不掉了。 再換一個新的?去蓋住舊的?...
    愿長夜將至閱讀 202評論 0 0
  • 在一次邏輯思維的跨年晚會上,羅胖曾以「帝王」來形容活在當(dāng)下移動互聯(lián)網(wǎng)世界的人們。一個手機(jī) App 可以讓你足不出戶...
    MrPeak閱讀 1,849評論 7 35