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