閉包、定時器

一、什么是閉包? 有什么作用

1.變量的作用域
??要理解閉包,首先必須理解JavaScript的變量作用域。變量的作用域無非就是兩種:全局變量和局部變量。在JavaScript中函數(shù)可以直接讀取外部的全局變量。

var a="你好";
function fun1(){
  alert(a);
}
fun1();//輸出"你好"

另一方面在函數(shù)外部,無法讀取函數(shù)內部的變量。

function fun2(){
  var a="你好";
}
alert(a);//瀏覽器提示錯誤,VM55:4 Uncaught ReferenceError: a is not defined(…)

這里有一個問題需要注意,函數(shù)內部聲明變量的時候,一定要使用var聲明,如果不使用var聲明,實際上是一個全局變量。

function fun2(){
  a="你好";
}
fun2();
alert(a);//"你好"

2.如何從外部讀取局部變量
??當我們需要獲取到函數(shù)內部的變量的時候,我們就需要在函數(shù)的內部在定義一個函數(shù)。

function fun1(){
  var a="你好";
  function fun2(){
    alert(a);//"你好"
  }
  return fun2();
}
fun1();

在上面的代碼中,函數(shù)fun2就被包括在函數(shù)fun1內部,這時fun1內部的所有局部變量,對fun2都是可見的。但是反過來就不行,fun2內部的局部變量,對fun1就是不可見的。這就是Javascript語言特有的"作用域鏈"結構(chain scope),子對象會一級一級地向上尋找所有父對象的變量。所以,父對象的所有變量,對子對象都是可見的,反之則不成立。
??既然fun2可以讀取fun1中的局部變量,那么只要把fun2做為返回值就可以獲取到fun1中的變量了。那么函數(shù)fun2就可以成為閉包了。

3.閉包的概念
??由于在Javascript中,只有函數(shù)內部的子函數(shù)才能讀取局部變量,因此可以把閉包簡單理解成"定義在一個函數(shù)內部的函數(shù)"。所以,在本質上,閉包就是將函數(shù)內部和函數(shù)外部連接起來的一座橋梁。

4.閉包的作用
??閉包可以用在許多地方。它的最大用處有兩個,一個是前面提到的可以讀取函數(shù)內部的變量,另一個就是讓這些變量的值始終保持在內存中。

5.使用閉包的注意事項
??由于閉包會使得函數(shù)中的變量都被保存在內存中,內存消耗很大,所以不能濫用閉包,否則會造成網頁的性能問題,在IE中可能導致內存泄露。解決方法是,在退出函數(shù)之前,將不使用的局部變量全部刪除。

二、setTimeout 0 有什么作用

1.setTimeout() 方法用于在指定的毫秒數(shù)后調用函數(shù)或計算表達式。
2.setTimeout(f,0)的作用就是為了把f放到運行隊列的最后去執(zhí)行。也就是說,無論setTimeout(f,0)寫在哪,當之前的函數(shù)執(zhí)行完之后,f可以在最后立即執(zhí)行。

示例

如上圖代碼所示,當1和3輸出之后,立即執(zhí)行的是2。

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

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

1.輸出的結果為10

結果

??我們可以先分析一下為什么輸出的結果為10:

示例

??如上圖所示,for循環(huán)內的函數(shù)可以寫成下面一種形式,因為return返回的是遍歷數(shù)組后的最后一個值10,所以最后的結果都是10。

2.方法一:賦值給立即執(zhí)行函數(shù),外部需要傳遞參數(shù)。

方法一

3.方法二:賦值給立即執(zhí)行函數(shù),聲明一個臨時變量存儲i的值,外部不需要傳參。

方法二

4.方法三:把它綁定在函數(shù)上,作為函數(shù)的一部分,不需要通過閉包,得到函數(shù)就能得到值。

方法三

四、使用閉包封裝一個汽車對象,可以通過如下方式獲取汽車狀態(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
方法

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

方法

1.setTimeout為延時性定時器,可以設置多長時間之后執(zhí)行代碼(只執(zhí)行一次)。
2.setInterval為間隔性定時器,可以設置每隔多久執(zhí)行一次代碼(執(zhí)行多次)。

六、寫一個函數(shù),計算setTimeout平均[備注:新加]最小時間粒度

方法

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

var a = 1;
setTimeout(function(){ 
     a = 2;
     console.log(a);
}, 0);
var a ;console.log(a);
a = 3;
console.log(a);
結果及原因

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

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

原因:以上代碼沒有輸出,因為setTimeout(f,0)會讓其包含的代碼在其它代碼執(zhí)行完后才能執(zhí)行;當執(zhí)行完第一行代碼后直接跳到while語句,而while語句中的判斷條件為真,將會一直執(zhí)行,進入死循環(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);
}

1.方法一:利用函數(shù)f()嵌套,形成閉包,輸出delayer+i的值。

方法一

2.方法二:

方法二
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 問題 1. 什么是閉包? 有什么作用? 概念:閉包就是能夠讀取其他函數(shù)內部變量的函數(shù)。由于在Javascript語...
    小木子2016閱讀 384評論 0 0
  • 問答 1.什么是閉包? 有什么作用? 閉包 簡而言之 就是讓函數(shù)外部可以訪問函數(shù)內的局部變量,就是將函數(shù)內部和函數(shù)...
    我是小韓閱讀 371評論 1 0
  • 一、什么是閉包?有什么作用 什么是閉包閉包是定義在一個函數(shù)內部的函數(shù),它可以訪問父級函數(shù)的內部變量。當一個閉包被創(chuàng)...
    __Qiao閱讀 834評論 0 0
  • 問題 一、什么是閉包? 有什么作用? 1.什么是閉包①JavaScript高級程序設計第三版定義閉包是指有權訪問另...
    鴻鵠飛天閱讀 575評論 0 0
  • 1.什么是閉包? 有什么作用 閉包指有權訪問另一個函數(shù)作用域的變量的函數(shù)。創(chuàng)建閉包的常見方式 是 在一個函數(shù)...
    JunVincetHuo閱讀 1,517評論 0 2

友情鏈接更多精彩內容