JavaScipt面向对象编程----闭包
? ? ? ? 在javascript中閉包是一個非常不好理解的概念,可是確實一個不可逃避的東西,那么今天我們就來一起學(xué)習(xí)一下閉包。 ? ? ? ? ?
? ? ? ? 什么是閉包?
? ? ? ? 閉包:官方”的解釋是:閉包是一個擁有很多變量和綁定了這些變量的環(huán)境的表達式(一般是一個函數(shù)),因而這些變量也是該表達式的一部分。相信讀完這句話以后,你就更加不知道什么是閉包了。事實上通俗的說閉包就是一個函數(shù)a內(nèi)部的局部變量s,被該函數(shù)內(nèi)部的函數(shù)b所使用,而且a函數(shù)返回值為b函數(shù)。那么我們就將b函數(shù)成為閉包。
? ? ? ? 為什么會產(chǎn)生閉包這個概念呢?那就要談?wù)勛兞孔饔糜虻膯栴}了。
? ? ? ? 變量的作用域無非就是兩種:全局變量和局部變量。
? ? ? ? Javascript語言的特殊之處,就在于函數(shù)內(nèi)部能夠直接讀取全局變量。
? ? ? ? Js代碼
? ? ? ? 還有一方面,在函數(shù)外部自然無法讀取函數(shù)內(nèi)的局部變量。
? ? ? ? Js代碼
functionf1(){varn=999; } alert(n); //彈出對話框:error
? ? ? ? ?這里有一個地方須要注意,函數(shù)內(nèi)部聲明變量的時候,一定要使用var命令。假設(shè)不用的話,你實際上聲明了一個全局變量!
? ? ? ? ?Js代碼
<span style="font-size:18px;">functionf1(){n=999; } f1(); alert(n); //999</span>? ? ? ? ?那么怎樣從外部讀取局部變量?
? ? ? ? ?出于種種原因,我們有時候須要得到函數(shù)內(nèi)的局部變量。可是,前面已經(jīng)說過了,正常情況下,這是辦不到的,僅僅有通過變通方法才干實現(xiàn)。那就是在函數(shù)的內(nèi)部,再定義一個函數(shù)。
? ? ? ? Js代碼
<span style="font-size:18px;">functionf1(){varn=999;functionf2(){alert(n); // 999} }</span>? ? ? ? 在上面的代碼中,函數(shù)f2就被包含在函數(shù)f1內(nèi)部,這時f1內(nèi)部的全部局部變量,對f2都是可見的。可是反過來就不行,f2內(nèi)部的局部變量,對f1 就是不可見的。這就是Javascript語言特有的“鏈?zhǔn)阶饔糜颉苯Y(jié)構(gòu)(chainscope),子對象會一級一級地向上尋找全部父對象的變量。所以,父對象的全部變量,對子對象都是可見的,反之則不成立。
? ? ? ?既然f2能夠讀取f1中的局部變量,那么僅僅要把f2作為返回值,我們不就能夠在f1外部讀取它的內(nèi)部變量了嗎!
? ? ? ?Js代碼
<span style="font-size:18px;">functionf1(){varn=999;functionf2(){alert(n);}returnf2; } varresult=f1(); result(); //999</span>?????? 這個我們在函數(shù)函數(shù)f1的外部就能夠讀取到f1內(nèi)的變量n的值了。
? ? ? ?大家可能注意到了,這個函數(shù)函數(shù)跟我上邊的描寫敘述好像非常吻合,沒錯,這就是閉包了。
? ? ? ?那么總結(jié)一下閉包都具備哪些特點呢?
? ? ? ?1,閉包外層是個函數(shù).
? ? ? ?2,閉包內(nèi)部都有函數(shù).
? ? ? ?3,閉包會return內(nèi)部函數(shù).
? ? ? ?4,閉包返回的函數(shù)內(nèi)部不能有return.(由于這樣就真的結(jié)束了)
? ? ? ?閉包有什么作用呢?
? ? ? ?一個是像上邊所說的那樣,在函數(shù)外邊訪問函數(shù)內(nèi)部的變量。還有一個就是讓這些變量的值始終保持在內(nèi)存中。怎么理解他的第二個作用呢?
? ? ? 看一下下邊這個樣例:
<span style="font-size:18px;">Js代碼 functionf1(){varn=999;functionf2(){alert(++n);}returnf2; } varresult=f1(); result(); // 999 result(); //1000</span>? ? ? ? 大家能夠看到兩次運行同一個函數(shù),結(jié)果卻是不一樣的,這個是為什么呢?為什么不像其它語言那個,一個函數(shù)運行完以后就被垃圾機制回收呢??原因就在javascript的垃圾回收機制中,在Javascript中,假設(shè)一個對象不再被引用,那么這個對象就會被GC回收。假設(shè)兩個對象互相引用,而不再被第3者所引用,那么這兩個互相引用的對象也會被回收。由于函數(shù)f1被f2引用,f2又被f1外的c引用,這就是為什么函數(shù)f1運行后不會被回收的原因。
? ? ? ? ?使用閉包函數(shù)應(yīng)該注意的問題;
? ? ? ? ?1)因為閉包會使得函數(shù)中的變量都被保存在內(nèi)存中,內(nèi)存消耗非常大,所以不能濫用閉包,否則會造成網(wǎng)頁的性能問題,在IE中可能導(dǎo)致內(nèi)存泄露。解決方法是,在退出函數(shù)之前,將不使用的局部變量所有刪除。
? ? ? ? ?2)閉包會在父函數(shù)外部,改變父函數(shù)內(nèi)部變量的值。所以,假設(shè)你把父函數(shù)當(dāng)作對象(object)使用,把閉包當(dāng)作它的公用方法(PublicMethod),把內(nèi)部變量當(dāng)作它的私有屬性(privatevalue),這時一定要小心,不要隨便改變父函數(shù)內(nèi)部變量的值。
? ? ? ? ?閉包(closure)是Javascript語言的一個難點,也是它的特色,非常多高級應(yīng)用都要依靠閉包實現(xiàn).所以學(xué)號閉包我們通往高級js程序猿的一個必由之路。
?
轉(zhuǎn)載于:https://www.cnblogs.com/mengfanrong/p/4030667.html
總結(jié)
以上是生活随笔為你收集整理的JavaScipt面向对象编程----闭包的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SASS官方文档
- 下一篇: Java多线程开发系列之四:玩转多线程(