閉包,定時(shí)器

問(wèn)題

1.什么是閉包? 有什么作用

閉包(英語(yǔ):Closure),又稱(chēng)詞法閉包(Lexical Closure)或函數(shù)閉包(function closures),是引用了自由變量的函數(shù)。這個(gè)被引用的自由變量將和這個(gè)函數(shù)一同存在,即使已經(jīng)離開(kāi)了創(chuàng)造它的環(huán)境也不例外。所以,有另一種說(shuō)法認(rèn)為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實(shí)體。閉包在運(yùn)行時(shí)可以有多個(gè)實(shí)例,不同的引用環(huán)境和相同的函數(shù)組合可以產(chǎn)生不同的實(shí)例。
在函數(shù)內(nèi)定義的變量,在其內(nèi)部返回函數(shù),返回的函數(shù)使用函數(shù)定義的變量,就會(huì)形成閉包;閉包可以減少全局變量,還可以對(duì)函數(shù)進(jìn)行封裝;
下面例子形成了簡(jiǎn)單的閉包

function f1() {
       var a=10;
       var b=20;
       function f2() {
           console.log(a);
       }
       f2();
   }
   f1();

應(yīng)用更多的形式:

function f1() {
       var a=10;
       var b=20;
       return function f2() {
           console.log(a);
       }
       
   }
   var result=f1();
   console.log(result());

2.setTimeout 0 有什么作用

使用setTimeout 0可以實(shí)現(xiàn)異步,可以等待當(dāng)前任務(wù)完成之后,在執(zhí)行setTimeout 0里面函數(shù)的內(nèi)容,因?yàn)閖avascript是單線程執(zhí)行代碼的,無(wú)法同時(shí)執(zhí)行多段代碼,所以當(dāng)一個(gè)代碼執(zhí)行的時(shí)候,后續(xù)的代碼必須等待,形成一個(gè)隊(duì)列,一旦當(dāng)前任務(wù)執(zhí)行完畢,才從隊(duì)列中取出下面的一個(gè)任務(wù)執(zhí)行,使用seTimeout 0就是利用了這個(gè)特性來(lái)延遲執(zhí)行順序。

代碼題

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

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

輸出10;
方法一:

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

方法二:

function f() {
        function test(x) {
            return function() {
                return x;
            }
        }
        var a = [];
        for (var i = 0; i < 10; i++) {
            a[i] = test(i);
        }
        return a;
    }
    var fnArr = f();
    console.log(fnArr[9]()); //

2.使用閉包封裝一個(gè)汽車(chē)對(duì)象,可以通過(guò)如下方式獲取汽車(chē)狀態(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 speed = 0;
        var status = 'stop';
        var acceleratevalue = 10;
        var deceleratevalue = -10;

        function getSpeed() {
            console.log(speed);
        }

        function setSpeed(num) {
            speed = num;
            console.log(speed);
        }

        function accelerate() {
            speed += acceleratevalue;
            console.log(speed);
        }

        function decelerate() {
            speed += deceleratevalue;
            console.log(speed);
        }

        function getStatus() {
            status = speed > 0 ? 'running' : 'stop';
            console.log(status);
        }
        return {
            setSpeed: setSpeed,
            getSpeed: getSpeed,
            accelerate: accelerate,
            decelerate: decelerate,
            getStatus: getStatus
        }
    })();
    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

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

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

4.寫(xiě)一個(gè)函數(shù),計(jì)算setTimeout最小時(shí)間粒度

function getMini() {
        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, 2)
        }, 2)
    }

    console.log(getMini())

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

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

setTimeout函數(shù)放在其他語(yǔ)句后面執(zhí)行,輸出1,3,2

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

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

//無(wú)限循環(huán)沒(méi)有輸出。flag的初始值為true,而setTimeout的delay值被設(shè)為0,也就意味著里面的函數(shù)要等待其他語(yǔ)句全部執(zhí)行完畢才會(huì)運(yùn)行。而while(flag){}因?yàn)閒lag為true的關(guān)系永遠(yuǎn)不會(huì)停止,所以console.log(flag)也就永遠(yuǎn)不會(huì)執(zhí)行。

7.下面這段代碼輸出?如何輸出delayer: 0, delayer:1...

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

輸出

0
1
2
3
4
delayer:4
delayer:4
delayer:4
delayer:4
delayer:4

輸出delayer: 0, delayer:1...

for (var i = 0; i < 5; i++) {
        setTimeout(
            (function(num) {
                return function() {
                    console.log('delayer:' + num);
                }
            })(i), 0);
        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
  • 1.什么是閉包? 有什么作用 定義:閉包就是嵌套在函數(shù)里面的內(nèi)部函數(shù),并且該內(nèi)部函數(shù)可以訪問(wèn)外部函數(shù)中聲明的所有局...
    饑人谷區(qū)子銘閱讀 1,066評(píng)論 0 2
  • 本教程版權(quán)歸小圓和饑人谷所有,轉(zhuǎn)載須說(shuō)明來(lái)源 問(wèn)題 什么是閉包? 有什么作用閉包(closure)是指有權(quán)訪問(wèn)另一...
    饑人谷__小圓閱讀 534評(píng)論 0 0
  • 1.什么是閉包? 有什么作用 閉包指有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域的變量的函數(shù)。創(chuàng)建閉包的常見(jiàn)方式 是 在一個(gè)函數(shù)...
    JunVincetHuo閱讀 1,512評(píng)論 0 2
  • 問(wèn)答 1.什么是閉包? 有什么作用? 閉包 簡(jiǎn)而言之 就是讓函數(shù)外部可以訪問(wèn)函數(shù)內(nèi)的局部變量,就是將函數(shù)內(nèi)部和函數(shù)...
    我是小韓閱讀 364評(píng)論 1 0

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