日夜談——定時器和閉包

來來來,談談閉包和計時器
1.什么是閉包? 有什么作用?

<li>閉包是指有權訪問其他函數作用域中的變量的函數
<li>詳細解釋:就是在一個函數中,父函數return出另一個子函數,并將子函數賦值給一個外部變量,使得此變量能夠訪問函數內部的值和變量,使得函數的內存不能釋放,因此生成一個閉包。

For example:

閉包.png

上面例子c作為一個外部函數,能夠訪問fn1和fn2的變量和值,因此這個c就是閉包!!!

<li>作用:</br>
1.可以訪問函數內部的變量和修改。</br>
2.讓函數內部的變量始終保存在內存中,不會因為函數執行完畢就銷毀。

<li>閉包的特點?
閉包的特點很鮮明,閉包內,變量無法釋放,無法被直接訪問;閉包可以被延遲執行。

<li>閉包的使用場景?
場景一:采用函數引用方式的setTimeout調用.
場景二:將函數關聯到對象的實例方法.
場景三:封裝相關的功能集

參考資料:<a >閉包使用場景</a>

2. setTimeout 0 有什么作用?

<li>setTimeout(func,ms)的作用是延遲指定毫秒數去執行此函數。
<li>setTimeout有最小時間間隔(4ms-16ms),因此即使你設置setTimeout(func,1)也不會在一毫秒之后執行,而是在最小時間間隔之后執行,比如4毫秒之后。
<li>setTimeout(func,0)的意思是,作用是讓f在現有的任務(腳本的同步任務和“消息隊列”指定的任務)一結束就立刻執行。簡單來說:就是當所有任務執行完成之后,馬上執行此函數。

3.代碼

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

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

code1:

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

code2:

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

2.使用閉包封裝一個汽車對象,可以通過如下方式獲取汽車狀態

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

code

    var Car = (function car(){
        var speed = 0;
        function setSpeed(n){
            speed = n;
        }
        function getSpeed(){
            console.log(speed);
        }
        function accelerate(){
            speed = speed + 10;
        }
        function decelerate(){
            speed = speed - 10;
        }
        function getStatus(){
            if(speed > 0){
                return 'running';
            }
            if(speed = 0){
                return 'stop';
            }
        }
        return {
            'setSpeed':setSpeed,
            'getSpeed':getSpeed,
            'accelerate':accelerate,
            'decelerate':decelerate,
            'getStatus':getStatus,
            'speed':'error'
        }
    })();
3.寫一個函數使用setTimeout模擬setInterval的功能?

code

        var i = 0 ;
        function copySetinterval(){
                setTimeout(function (){
                console.log(i++);
                copySetinterval();
            },1000);
        };
        copySetinterval()
寫一個函數,計算setTimeout平均最小時間粒度
function getMini(){
    var i = 0;
    var start = Date.now();
    var time  = setTimeout(function (){
        i++;
        if(i === 1000){
            clearTimeout(time);
            var end = Date.now();
            console.log((end-start)/i);
        }
        time = setTimeout(arguments.callee,0);
    } ,0)
}
getMini()
4.下面這段代碼輸出結果是? 為什么?
var a = 1;
setTimeout(function(){
    a = 2;
    console.log(a);
}, 0);
var a ;
console.log(a);
a = 3;
console.log(a);

變形得:

var a = 1;
var a ;
console.log(a);
a = 3;
console.log(a);
setTimeout(function(){
    a = 2;
    console.log(a);
}, 0);

答:執行結果按順序排列,分別是1,3,2。
解釋:因為setTimeout是指所有任務執行完畢后,延遲執行多少毫秒執行函數,因此setTimeout是最后執行,如上面的代碼,首先定義變量a=1,因此第一個console.log(a)為1,之后將3賦給變量a,因此第二個console.log(a)為3,最后執行setTimeout,里面的匿名函數將2賦值給a,因此第三個console.log輸出是2.

5.下面這段代碼輸出結果是? 為什么?
var flag = true; 
setTimeout(function(){
    flag = false;
},0)
while(flag){}
console.log(flag);

變形得

var flag = true; // 把布爾值true賦值給變量flag;
while(flag){} //當flag為true時執行while循環,但是while循環是個死循環,所以后面代碼全部不會執行;
console.log(flag);
setTimeout(function(){
    flag = false;
},0)

因此沒有輸出。

6.下面這段代碼輸出?如何輸出delayer: 0, delayer:1...(使用閉包來實現)
for(var i=0;i<5;i++){
    setTimeout(function(){
         console.log('delayer:' + i );
    }, 0);
    console.log(i);
}

code

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

版權歸饑人谷peter和饑人谷所有,若有轉載,請注明來源

感謝瓜子觀眾:


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

推薦閱讀更多精彩內容

  • 什么是閉包? 有什么作用閉包:函數對象可以通過作用域鏈相互關聯,函數體內部的變量可以保存在函數的作用域內。 上述代...
    coolheadedY閱讀 754評論 0 0
  • 閉包 定義「一個函數」+「訪問到的外部變量」= 閉包 作用創建內部變量,既不能被外部隨意修改,又可以通過指定的函數...
    jrg_memo閱讀 529評論 0 0
  • 問答 什么是閉包? 有什么作用答:“官方”的解釋是:閉包是一個擁有許多變量和綁定了這些變量的環境的表達式(通常是一...
    饑人谷_桶飯閱讀 231評論 0 0
  • 1.什么是閉包? 有什么作用 閉包就是能夠讀取其他函數內部變量的函數,也就是定義在函數內部的函數; 函數retur...
    成熟穩重的李先生閱讀 358評論 0 2
  • 雨過會天晴 天晴了有機會 看到彩虹 彩虹是七色的……
    雨水風晴閱讀 234評論 0 0