欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

javascript閉包(Closure)用法實例簡析

 更新時間:2015年11月30日 09:31:05   作者:JeffWong  
這篇文章主要介紹了javascript閉包(Closure)用法,結(jié)合實例形式較為詳細的分析了JavaScript閉包的概念、功能及使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下

本文實例講述了javascript閉包(Closure)用法。分享給大家供大家參考,具體如下:

closure被翻譯成“閉包”,感覺這東西被包裝的太學術(shù)化。下面參考書本和網(wǎng)上資源簡單探討一下(理解不當之處務(wù)請留意)。

1、什么是閉包

官方的回答:所謂“閉包”,指的是一個擁有許多變量和綁定了這些變量的環(huán)境的表達式(通常是一個函數(shù)),因而這些變量也是該表達式的一部分。

看了上面的定義,如果你不是高手,我堅信你會和我一樣憤怒的質(zhì)問:這tmd是人話嗎?
要理解閉包,還是代碼最有說服力啊,上代碼:

function funcTest()
{
 var tmpNum=100; //私有變量
 //在函數(shù)funcTest內(nèi)定義另外的函數(shù)作為funcTest的方法函數(shù)
 function innerFuncTest(
 {
    alert(tmpNum); //引用外層函數(shù)funcTest的臨時變量tmpNum
 }
 return innerFuncTest; //返回內(nèi)部函數(shù)
}
//調(diào)用函數(shù)
var myFuncTest=funcTest(); 
myFuncTest();//彈出100

上面代碼中,注釋已經(jīng)寫的清清楚楚?,F(xiàn)在我們可以這么理解“閉包”:在函數(shù)體內(nèi)定義另外的函數(shù)作為目標對象的方法函數(shù)(示例中就是在函數(shù)funcTest內(nèi)定義另外的函數(shù)innerFuncTest作為funcTest的方法函數(shù)),而這個對象的方法函數(shù)反過來引用外層函數(shù)體中的臨時變量(閉包是一種間接保持變量值的機制。示例中就是內(nèi)部函數(shù)innerFuncTest引用外層函數(shù)funcTest的臨時變量tmpNum,這里必須注意,臨時變量可以包括外部函數(shù)中聲明的所有局部變量、參數(shù)和聲明的其他內(nèi)部函數(shù))。當其中一個這樣的內(nèi)部函數(shù)在包含它們的外部函數(shù)之外被調(diào)用時,就會形成閉包(示例中,調(diào)用函數(shù)的時候,myFuncTest實際調(diào)用的是innerFuncTest函數(shù),也就是說funcTest的一個內(nèi)部函數(shù)innerFuncTest在funcTest之外被調(diào)用,這時就創(chuàng)建了一個閉包)。

2、兩個利用閉包的例子

下面舉兩個例子,一個是因為閉包導致了問題,而另一個則利用閉包巧妙地通過函數(shù)的作用域綁定參數(shù)。

這兩個例子相關(guān)的HTML標記片斷如下:

<a href="#" id="closureTest0">利用閉包的例子(1秒后會看到提示)</a><br />
<a href="#" id="closureTest1">由于閉包導致問題的例子1</a><br />
<a href="#" id="closureTest2">由于閉包導致問題的例子2</a><br />
<a href="#" id="closureTest3">由于閉包導致問題的例子3</a><br />

(1)、因閉包而導致問題

上面的HTML標記片斷中有4個<a>元素,現(xiàn)在要給后三個指定事件處理程序,使它們在用戶單擊時報告自己在頁面中的順序,比如:當用戶單擊第2個鏈接時,報告“您單擊的是第1個鏈接”。為此,如果編寫下列為后三個鏈接添加事件處理程序的函數(shù):

function badClosureExample(){
  for (var i = 1; i <4; i++) {
    var element = document.getElementById('closureTest' + i);
    element .onclick = function(){
      alert('您單擊的是第' + i + '個鏈接');
    }
  }
}

然后,在頁面載入完成后(不然可能會報錯)調(diào)用該函數(shù):

window.onload = function(){
  badClosureExample();
}

看一下運行結(jié)果,此時單擊后3個鏈接,會看到警告框中顯示什么信息呢?——全都是“您單擊的是第4個鏈接”。是不是令你感到十分意外?為什么?

分析:因為在badClosureExample()函數(shù)中指定給element.onclick的事件處理程序,也就是onclick那個匿名函數(shù)是在badClosureExample()函數(shù)運行完成后(用戶單擊鏈接時)才被調(diào)用的。而調(diào)用時,需要對變量i求值,解析程序首先會在事件處理程序內(nèi)部查找,但i沒有定義。然后,又到 badClosureExample()函數(shù)中查找,此時有定義,但i的值是4(只有i大于4才會停止執(zhí)行for循環(huán))。因此,就會取得該值——這正是閉包(匿名函數(shù))要使用其外部函(badClosureExample)作用域中變量的結(jié)果。而且,這也是由于匿名函數(shù)本身無法傳遞參數(shù)(故而無法維護自己的作用域)造成的。

那么這個例子的問題怎么解決呢?其實方法有很多(自己不妨寫一下看看),我認為比較簡單直接的代碼:

function popNum(oNum){
  return function(){
          alert('您單擊的是第'+oNum+'個鏈接');
  }
}
function badClosureExample(){
  for (var i = 1; i <4; i++) {
    var element = document.getElementById('closureTest' + i);
    element .onclick =new popNum(i);
    }
}

(2)、巧妙利用閉包綁定參數(shù)

還是上面的HTML片段,我們要在用戶單擊第一個鏈接時延時彈出一個警告框,怎么實現(xiàn)?答案是使用setTimeout()函數(shù),這個函數(shù)會在指定的毫秒數(shù)之后調(diào)用一個函數(shù),如:

復制代碼 代碼如下:
setTimeout(someFunc,1000);

但問題是,無法給其中的someFunc函數(shù)傳遞參數(shù)。而使用閉包則可以輕松解決這個問題:

function goodClosureExample(oMsg){
  return function(){
    alert(oMsg);
  };
}

函數(shù)goodClosureExample用來返回一個匿名函數(shù)(閉包)。而我們可以通過為它傳遞參數(shù)來使返回的匿名函數(shù)綁定該參數(shù),如:

復制代碼 代碼如下:
var good = goodClosureExample('這個參數(shù)是通過閉包綁定的');

而此時,就可以將綁定了參數(shù)的good函數(shù)傳遞給setTimeout()實現(xiàn)延時警告了:
復制代碼 代碼如下:
setTimeout(good,1000) //此時good中已經(jīng)綁定了參數(shù)

最后,測試通過的完整代碼:

window.onload = function(){
  var element = document.getElementById('closureTest0');
  if (element) {
    var good = goodClosureExample('這個參數(shù)是由閉包綁定的');
    element.onclick = function(){
      setTimeout(good, 1000); //延遲1秒彈出提示
    }
  }
}

3、javascript的垃圾回收原理

(1)、在javascript中,如果一個對象不再被引用,那么這個對象就會被GC回收;

(2)、如果兩個對象互相引用,而不再被第3者所引用,那么這兩個互相引用的對象也會被回收。

在js中使用閉包,往往會給javascript的垃圾回收器制造難題。尤其是遇到對象間復雜的循環(huán)引用時,垃圾回收的判斷邏輯非常復雜,搞不好就有內(nèi)存泄漏的危險,所以,慎用閉包。ms貌似已經(jīng)不建議使用閉包了。

希望本文所述對大家JavaScript程序設(shè)計有所幫助。

相關(guān)文章

  • js微信掃描二維碼登錄網(wǎng)站技術(shù)原理

    js微信掃描二維碼登錄網(wǎng)站技術(shù)原理

    這篇文章主要介紹了js微信掃描二維碼登錄網(wǎng)站技術(shù)原理,具有一定的參考價值,有需要的可以了解一下。
    2016-12-12
  • JavaScript實戰(zhàn)之菜單特效

    JavaScript實戰(zhàn)之菜單特效

    這篇文章主要為大家詳細介紹了JavaScript實戰(zhàn)之菜單特效實現(xiàn)代碼,具有與一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-08-08
  • JavaScript+CSS實現(xiàn)的可折疊二級菜單實例

    JavaScript+CSS實現(xiàn)的可折疊二級菜單實例

    這篇文章主要介紹了JavaScript+CSS實現(xiàn)的可折疊二級菜單,以完整實例形式分析了JavaScript基于頁面元素節(jié)點及樣式的動態(tài)操作實現(xiàn)折疊菜單的相關(guān)技巧,需要的朋友可以參考下
    2016-02-02
  • Echart中國地圖更換背景圖的方法示例

    Echart中國地圖更換背景圖的方法示例

    本文主要介紹了Echart中國地圖更換背景圖的方法示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • js中的for如何實現(xiàn)foreach中的遍歷

    js中的for如何實現(xiàn)foreach中的遍歷

    js中沒有foreach這個關(guān)鍵字,但是可以用var v in array來實現(xiàn)遍歷,下面有個不錯的示例,大家可以參考下
    2014-05-05
  • JavaScript中new操作符的原理示例詳解

    JavaScript中new操作符的原理示例詳解

    javascript中的new是一個語法糖,new的過程實際上是創(chuàng)建一個新對象,把新象的原型設(shè)置為構(gòu)造器函數(shù)的原型,這篇文章主要給大家介紹了關(guān)于JavaScript中new操作符原理的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • SWFUpload多文件上傳及文件個數(shù)限制的方法

    SWFUpload多文件上傳及文件個數(shù)限制的方法

    這篇文章主要介紹了SWFUpload多文件上傳及文件個數(shù)限制的方法,較為詳細的分析了SWFUpload組件實現(xiàn)多文件上傳的原理、使用方法與相關(guān)注意事項,需要的朋友可以參考下
    2016-05-05
  • js面向?qū)ο蠓绞綄崿F(xiàn)拖拽效果

    js面向?qū)ο蠓绞綄崿F(xiàn)拖拽效果

    這篇文章主要為大家詳細介紹了js面向?qū)ο蠓绞綄崿F(xiàn)拖拽效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • JavaScript中的值類型轉(zhuǎn)換介紹

    JavaScript中的值類型轉(zhuǎn)換介紹

    這篇文章主要介紹了JavaScript中的值類型轉(zhuǎn)換介紹,本文講解了值類型轉(zhuǎn)換規(guī)則、值類型轉(zhuǎn)換與比較、顯式類型轉(zhuǎn)換、對類型自動轉(zhuǎn)換的使用等內(nèi)容,需要的朋友可以參考下
    2014-12-12
  • element中el-switch的v-model自定義值的實現(xiàn)

    element中el-switch的v-model自定義值的實現(xiàn)

    在el-switch中設(shè)置active-value和inactive-value屬性,接受Boolean, String或Number類型的值,本文就來介紹一下element中el-switch的v-model自定義值的實現(xiàn),感興趣的可以了解一下
    2023-11-11

最新評論