亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 語言 > JavaScript > 正文

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

2024-05-06 16:25:30
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了javascript閉包(Closure)用法,結合實例形式較為詳細的分析了JavaScript閉包的概念、功能及使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下
 

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

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

1、什么是閉包

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

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

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

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

2、兩個利用閉包的例子

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

這兩個例子相關的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>元素,現在要給后三個指定事件處理程序,使它們在用戶單擊時報告自己在頁面中的順序,比如:當用戶單擊第2個鏈接時,報告“您單擊的是第1個鏈接”。為此,如果編寫下列為后三個鏈接添加事件處理程序的函數:

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

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

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

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

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

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

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)、巧妙利用閉包綁定參數

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

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

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

 

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

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

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

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

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

 

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

3、javascript的垃圾回收原理

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

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

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

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



注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久福利视频网| 亚洲欧美www| 亚洲欧美色图片| 日韩视频亚洲视频| 日韩电影视频免费| 国产精品一区久久| 午夜精品一区二区三区在线| 欧美日韩视频在线| 国产一区二区三区网站| 亚洲国产精品中文| 国产97在线观看| 亚洲激情 国产| 在线午夜精品自拍| 久久精品电影网站| 国产色婷婷国产综合在线理论片a| 久久久噜噜噜久久中文字免| 久久久免费高清电视剧观看| 成人国内精品久久久久一区| 午夜精品美女自拍福到在线| 欧美视频一二三| 亚洲aⅴ日韩av电影在线观看| 亚洲欧美日韩国产成人| 国产精品96久久久久久又黄又硬| 久久久久久久久久亚洲| 精品综合久久久久久97| 国产亚洲精品久久久优势| 日韩精品在线影院| www.久久久久久.com| 亚洲欧美日韩综合| 在线观看欧美www| 色综合久久天天综线观看| 国产精品免费久久久久影院| 日韩国产高清污视频在线观看| 国产日韩欧美在线播放| 国产精品永久免费在线| 亚洲xxxx3d| 亚洲精品视频在线播放| 久久高清视频免费| 久青草国产97香蕉在线视频| 欧美另类99xxxxx| 亚洲天堂一区二区三区| 欧美激情精品久久久久久黑人| 欧美激情欧美激情| 国产+人+亚洲| 日本国产高清不卡| 日韩成人在线免费观看| 国产精品对白刺激| 亚洲最大的av网站| 97色伦亚洲国产| 国产精品视频成人| 欧美日韩一区二区三区在线免费观看| 亚洲欧美制服另类日韩| 亚洲精品中文字幕女同| 国产精品影片在线观看| 91精品中国老女人| 91系列在线播放| 亚洲精品美女免费| 超碰精品一区二区三区乱码| 中文字幕精品影院| 国产精品日本精品| 国产免费成人av| 久久亚洲影音av资源网| 日韩中文字幕网| 久久成人这里只有精品| 亚洲女人天堂网| 在线观看日韩www视频免费| 欧美久久久精品| 久久久久久久国产精品视频| 在线观看日韩欧美| 国产精品久久久久免费a∨| 亚洲国产精品久久精品怡红院| 国产成人小视频在线观看| 欧美自拍大量在线观看| 亚洲电影第1页| 国产欧美一区二区三区在线| 欧美日韩国产黄| 久久久久久国产精品三级玉女聊斋| 日韩在线高清视频| 久久久91精品国产| 国产中文日韩欧美| 中文字幕成人精品久久不卡| 欧美激情视频在线观看| 日韩av中文字幕在线播放| 日韩av免费在线播放| 4438全国成人免费| 91在线看www| 成人免费视频在线观看超级碰| 日韩成人在线播放| 91在线观看免费高清| 久久久久久久网站| 国产999在线观看| 2021久久精品国产99国产精品| 久久在线免费视频| www.亚洲天堂| 2020欧美日韩在线视频| 亚洲91精品在线观看| 欧美高清videos高潮hd| 日韩美女激情视频| 日韩高清av一区二区三区| 国产一区二区三区久久精品| 欧美电影免费观看大全| 亚洲电影成人av99爱色| 欧美一区三区三区高中清蜜桃| 日韩暖暖在线视频| xxxxxxxxx欧美| 欧美亚洲在线视频| 亚洲一区二区少妇| 国产偷亚洲偷欧美偷精品| 欧洲亚洲免费在线| 日韩精品亚洲元码| 国产精品美女无圣光视频| 精品久久久在线观看| 一区二区三区国产在线观看| 51ⅴ精品国产91久久久久久| 91精品国产91久久久久久久久| 91精品国产99| 色婷婷综合久久久久中文字幕1| 色偷偷偷综合中文字幕;dd| 欧美亚洲成人免费| 日韩av在线电影网| 日本精品视频在线| 久久久精品视频在线观看| 在线精品国产成人综合| 国产精品久久婷婷六月丁香| 欧美激情图片区| 综合国产在线观看| 日本精品va在线观看| 欧美日韩亚洲精品内裤| 日韩中文字幕第一页| 国产成人午夜视频网址| 欧美最猛黑人xxxx黑人猛叫黄| 久久综合免费视频影院| 久久97久久97精品免视看| 欧美另类在线播放| 亚洲aⅴ日韩av电影在线观看| 亚洲成人精品久久| 色综合色综合网色综合| 久久精品中文字幕| 亚洲在线观看视频网站| 日韩美女中文字幕| 91色琪琪电影亚洲精品久久| 久久久视频精品| 国产精品中文字幕在线| 国产婷婷成人久久av免费高清| 亚洲精品aⅴ中文字幕乱码| 国产精品欧美一区二区三区奶水| 国产精品观看在线亚洲人成网| 国产精品丝袜白浆摸在线| 永久555www成人免费| 欧美亚洲激情视频| 成人疯狂猛交xxx| 国产性色av一区二区| 精品久久久久久久久久ntr影视| 国产在线播放91| 精品在线小视频| 日韩高清电影免费观看完整版| 久久久久久久97| 亚洲一区二区少妇| 2019中文字幕在线观看| 国产一区二区三区欧美| 91精品国产自产在线观看永久| 亚洲精品v欧美精品v日韩精品| 色偷偷综合社区| 91成人在线视频|