麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 語(yǔ)言 > JavaScript > 正文

javascript閉包(Closure)用法實(shí)例簡(jiǎn)析

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

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

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

1、什么是閉包

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

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

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

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

2、兩個(gè)利用閉包的例子

下面舉兩個(gè)例子,一個(gè)是因?yàn)殚]包導(dǎo)致了問(wèn)題,而另一個(gè)則利用閉包巧妙地通過(guò)函數(shù)的作用域綁定參數(shù)。

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

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

(1)、因閉包而導(dǎo)致問(wèn)題

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

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

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

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

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

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

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

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

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

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

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

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

 

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

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

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

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

最后,測(cè)試通過(guò)的完整代碼:

 

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

3、javascript的垃圾回收原理

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

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

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

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



注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到JavaScript/Ajax教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: wankzhd| 日韩毛片免费观看 | 精品国产一区二 | 中文字幕一区2区 | 精品一区二区久久久久久久网精 | 亚洲第一成人在线视频 | 亚洲人成中文字幕在线观看 | 亚洲天堂岛国片 | 黄色av免费网站 | 天天干天天透 | 亚洲无限资源 | 久久蜜桃香蕉精品一区二区三区 | 久章草影院 | 成人三级免费电影 | 精品国产1区2区3区 av视屏 | 中文区中文字幕免费看 | 久久久一区二区精品 | 西川av在线一区二区三区 | a一级黄色大片 | 宅男噜噜噜66国产在线观看 | 国产69精品福利视频 | 成人福利视频在 | 久国产| 嫩呦国产一区二区三区av | 欧美成人国产va精品日本一级 | 九九午夜 | 有色视频在线观看 | 日本成年免费网站 | 法国性xxx精品hd专区 | 狼伊千合综网中文 | 黄在线免费看 | 国产精品久久99精品毛片三a | 国产午夜免费不卡精品理论片 | 亚洲午夜天堂吃瓜在线 | 欧美精品一区二区三区在线播放 | 性欧美极品xxxx欧美一区二区 | 亚洲成a人在线 | 97超级碰碰人国产在线观看 | 日本成人二区 | 亚洲天堂岛国片 | 精品一区二区三区在线观看视频 |