閉包

通常函數(shù)內(nèi)部可以隨意使用全局變量,但無(wú)法從外部讀取函數(shù)內(nèi)部的變量,因此,我們需要在函數(shù)的內(nèi)部,再定義一個(gè)函數(shù)。

function f1( ){

? ? var n=999;

? ? function f2( ){ //函數(shù)f2被包括在f1內(nèi)部,這時(shí)f1內(nèi)部的所有局部變量,對(duì)f2都是可見(jiàn)的

? ? ? ? alert(n); // 999

? ? }

}

既然f2可以讀取f1中的局部變量,那么只要把f2作為返回值,我們不就可以在f1外部讀取它的內(nèi)部變量了嗎。

function f1(){

? ? var n=999;

? ? function f2(){

? ? ? ? alert(n);

? ? }

? ? return f2;

}

var result=f1();

result(); // 999

閉包的概念

上面例子中的f2函數(shù),就是閉包。

簡(jiǎn)單來(lái)說(shuō),閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。

由于在Javascript語(yǔ)言中,只有函數(shù)內(nèi)部的子函數(shù)才能讀取局部變量,因此可以把閉包簡(jiǎn)單理解成"定義在一個(gè)函數(shù)內(nèi)部的函數(shù)"。

在本質(zhì)上,閉包就是將函數(shù)內(nèi)部和函數(shù)外部連接起來(lái)的一座橋梁。

閉包的五種寫(xiě)法

(1)定義函數(shù)Circle,給函數(shù)Circle添加一個(gè)area屬性

(2)聲明一個(gè)Circle變量,將一個(gè)函數(shù)當(dāng)作值賦給變量。(常用)

(3)new 一個(gè)對(duì)象(Object)為Circle,然后給對(duì)象添加屬性和方法。

(4)這種方法使用較多,也最為方便。var obj = {}就是聲明一個(gè)空的對(duì)象。(常用)

(5)不太常用


閉包的用途

(1)可以讀取函數(shù)內(nèi)部的變量。(如上面例子所說(shuō))

(2)讓這些變量的值始終保持在內(nèi)存中。

function f1( ){

? ? var n=999;

? ? nAdd= function(){n+=1}

? ? function f2(){

? ? ? ? alert(n);

? ? }

? ? return f2;

}

var result=f1();

result(); // 999

nAdd();

result(); // 1000

在這段代碼中,result實(shí)際上就是閉包f2函數(shù)。它一共運(yùn)行了兩次,第一次的值是999,第二次的值是1000。這證明了,函數(shù)f1中的局部變量n一直保存在內(nèi)存中,并沒(méi)有在f1調(diào)用后被自動(dòng)清除。

為什么會(huì)這樣呢?原因就在于f1是f2的父函數(shù),而f2被賦給了一個(gè)全局變量,這導(dǎo)致f2始終在內(nèi)存中,而f2的存在依賴(lài)于f1,因此f1也始終在內(nèi)存中,不會(huì)在調(diào)用結(jié)束后,被垃圾回收機(jī)制(garbage collection)回收。

這段代碼中另一個(gè)值得注意的地方,就是"nAdd=function(){n+=1}"這一行,首先在nAdd前面沒(méi)有使用var關(guān)鍵字,因此nAdd是一個(gè)全局變量,而不是局部變量。其次,nAdd的值是一個(gè)匿名函數(shù),而這個(gè)匿名函數(shù)本身也是一個(gè)閉包,所以nAdd相當(dāng)于是一個(gè)setter,可以在函數(shù)外部對(duì)函數(shù)內(nèi)部的局部變量進(jìn)行操作。

使用閉包的注意點(diǎn)

1)由于閉包會(huì)使得函數(shù)中的變量都被保存在內(nèi)存中,內(nèi)存消耗很大,所以不能濫用閉包,否則會(huì)造成網(wǎng)頁(yè)的性能問(wèn)題,在IE中可能導(dǎo)致內(nèi)存泄露。解決方法是,在退出函數(shù)之前,將不使用的局部變量全部刪除。

2)閉包會(huì)在父函數(shù)外部,改變父函數(shù)內(nèi)部變量的值。所以,如果你把父函數(shù)當(dāng)作對(duì)象(object)使用,把閉包當(dāng)作它的公用方法(Public Method),把內(nèi)部變量當(dāng)作它的私有屬性(private value),這時(shí)一定要小心,不要隨便改變父函數(shù)內(nè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)容

  • 閉包(closure)是Javascript語(yǔ)言的一個(gè)難點(diǎn),也是它的特色,很多高級(jí)應(yīng)用都要依靠閉包實(shí)現(xiàn)。 一、變量...
    zock閱讀 1,121評(píng)論 2 6
  • 閉包(closure)是Javascript語(yǔ)言的一個(gè)難點(diǎn),也是它的特色,很多高級(jí)應(yīng)用都要依靠閉包實(shí)現(xiàn)。 下面就是...
    魯uin閱讀 339評(píng)論 0 2
  • 卡爾維諾中文站留言板這個(gè)帖子專(zhuān)門(mén)用作卡爾維諾中文站的留言板,歡迎大家留言和提問(wèn)。...阮一峰2007-01-04T...
    舟漁行舟閱讀 400評(píng)論 0 1
  • 這次來(lái)泰國(guó)旅游有去到全世界最大的鱷魚(yú)湖,北攬鱷魚(yú)湖。在那里有三萬(wàn)多只的鱷魚(yú)都是養(yǎng)殖。 來(lái)到這里對(duì)鱷魚(yú)也是有了...
    一城山河閱讀 1,229評(píng)論 1 1
  • 9、ssh密鑰的配置和遠(yuǎn)程存庫(kù)中網(wǎng)頁(yè)類(lèi)型的設(shè)置 在于github進(jìn)行連接時(shí),普通模式的連接需要每次都輸入用戶(hù)名和密...
    Mongy閱讀 1,107評(píng)論 0 0

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