1. 程式人生 > >淺談JS中的閉包

淺談JS中的閉包

不能 程序 含義 函數 刪除 今天 func 空間 而且

  今天 大年初一,祝各位小夥伴們狗年旺旺啊,閑來也沒事,只能鉆研一下自己的分內之事,也就是作為一個前端碼農的身份,得時刻保持學習的態度,溫故而知新,每天都給自己一個小目標去完成,日積月累,所想達到的狀態,都會有所見長。

  JS中的閉包,想必,做web開發的程序猿們都有一定的認識吧,不僅僅是js裏有這種特性,而且弱語言類型的譬如python裏也是有閉包這麽一個強大的特性的,對於老司機們來說,閉包可真的是一個很好的東西,但是對於新入門的菜鳥們來說,閉包卻是一個難以搞得清楚的特性,很多情況下,會用,但是卻不能夠深刻理解其中的含義,有些時候,出現問題了,也無法立刻找出問題的所在。下面我們來聊一聊js中的閉包相關的知識。

一、什麽是閉包?

當一個內部函數被其外部函數之外的變量引用時,就形成了一個閉包。

簡單的來說,所謂的閉包就是一個具有封閉的對外不公開的,包裹結構或空間。


二、為什麽函數可以構成閉包?

閉包就是一個具有封閉與包裹功能的結構,是為了實現具有私有訪問空間的函數的。函數可以構成閉包。函數內部定義的數據函數外部無法訪問,即函數具有封閉性;函數可以封裝代碼即具有包裹性,所以函數可以構成閉包

三、閉包有什麽用(特性)

閉包的作用,就是保存自己私有的變量,通過提供的接口(方法)給外部使用,但外部不能直接訪問該變量。

當我們需要在模塊中定義一些變量,並希望這些變量一直保存在內存中但又不會“汙染”全局的變量時,就可以用閉包來定義這個模塊。

閉包的缺點:閉包的缺點就是常駐內存,會增大內存使用量,使用不當很容易造成內存泄露。

函數套函數就是閉包嗎?:不是!,當一個內部函數被其外部函數之外的變量引用時,才會形成了一個閉包。

四、閉包的基本模型

1、對象模式

函數內部定義個一個對象,對象中綁定多個函數(方法),返回對象,利用對象的方法訪問函數內的數據

function createPerson() {
    var __name__ = "";
    return {
        getName: function () {
            return __name__;
        },
        setName: 
function( value ) { // 如果不姓張就報錯 if ( value.charAt(0) === ‘張‘ ) { __name__ = value; } else { throw new Error( ‘姓氏不對,不能取名‘ ); } } } } var p = createPerson(); p.set_Name( ‘張三豐‘ ); console.log( p.get_Name() ); p.set_Name( ‘張王富貴‘ ); console.log( p.get_Name() );

2、函數模式

函數內部定義一個新函數,返回新函數,用新函數獲得函數內的數據

function foo() {
    var num = Math.random();
    function func() {
        return mun;
    }
    return func;
}
var f = foo();
// f 可以直接訪問這個 num
var res1 = f();
var res2 = f();

3、沙箱模式

沙箱模式就是一個自調用函數,代碼寫到函數中一樣會執行,但是不會與外界有任何的影響,比如jQuery

(function () {
   var jQuery = function () { // 所有的算法 }
   // .... // .... jQuery.each = function () {}
   window.jQuery = window.$ = jQuery;
})();
$.each( ... )

五、閉包的缺點

1、由於閉包會使得函數中的變量都保存在內存中,一方面會使內存消耗大,另一方面在ie下導致內存泄露,解決辦法,在退出函數時,將不使用的局部變量全部刪除(null掉吧)

2、閉包會在父級外部,改變父函數內部內部變量的值;所以,如果你把父函數當作對象(object)使用,把閉包當做它的公用方法,把內部變量當做它的私有屬性,這時你需要做的是,加倍小心,不要隨便改變函數的值,否則你會後悔的。

六、總結

對於閉包的活學活用,一直需要通過不斷地項目經驗的累積,才能每次都能得出更為深刻的認識,想要成為一名優秀的前端工程師,既要知其然,也要知其所以然,才能讓自己變得更加優秀。

淺談JS中的閉包