個人對js閉包的心得見解
談起閉包很多人都會撓頭。我以前也是,因此我查閱了很多資料,綜合分析和理解,自認現在已經識得了閉包的真面目。下面我就從閉包的產生條件,閉包的作用,閉包的實質,閉包的本質,閉包產生的時機,閉包的應用 等幾個方面具體和系統的闡述一下閉包。
前導
我們談閉包有一個前提條件:
一般情況下,函數執行完畢,它內部的變量會被銷毀。
現在我們在來看
閉包是一種語言特性,可以使嵌套的內部函數訪問並保存嵌套的外部函數的局部變量。外部函數執行完後,只要內部函數還存在,那其中保存外部函數的局部變量也會保存下來。可能看這句話有些繞,咱們往下看
閉包產生的條件:
1 存在函數嵌套,函數fun2在函數fun1執行時被定義,我們認為fun2是fun1的內部函數。
2 內部函數引用了外部函數的局部變量。
3 內部函數被暴露出來,可以在外部函數外調用,內部函數中訪問的外部函數的局部變量被保存下來,就形成了閉包。
閉包的作用:
1.延長了局部變量的生命周期
2.在函數外可以間接操縱內部局部變量
閉包的本質:
一種語言特性,在瀏覽器的具體實現中是內部函數對象內部的一個隱式對象【Closure】,用以保存內部函數引用的外部函數的局部變量。
(隱式變量:存在於瀏覽器內存中,幫助完成語法功能,但不能被程序員操作的對象)
如果有興趣可以用chrome開發者工具中Sources指令查一下函數執行時的棧結構附上一段調試代碼
閉包產生的時機:
訪問了外部函數局部變量的內部函數被定義時產生了閉包。閉包的生命周期取決於內部函數的生命周期。
閉包到底是內部函數被定義是產生,還是被暴露出去的時候產生?
經常有人會糾結這個問題,其實兩者說的都有道理,內部函數定義時就產生了閉包。但此時內部函數也是被外部函數的變量指向的。如果不把內部函數對象暴露出去,那等函數執行完內部變量對象也就被銷毀了,閉包也無從談起。
閉報的應用:
說起閉包,我們通常的認識這是一個高級語法,最大的作用就是提高逼格。
非也非也,其實我們也js代碼從來沒有離開過閉包。
我們曾經長期使用的Jq框架,就是必報的有力實踐者。大家知道的,先進大部分的框架和模塊都是用IIFE封裝的。所以我們使用的方法和屬性都是這個自調用函數的內部變量。
我們使用的$的方法中有保存著大量的IIFE的內部資源。這變量都保存在暴露出來的方法的閉包中。
我們在寫較復雜的原生代碼時也經常會使用到閉包,只是我們不經意而已。這就是所謂的語法糖。
案例
閉包的魅力和招人恨的的能力,從來不是因為這個概念有多難理解。而是它可以讓代碼有很多“玩法”,這些玩法通常會顛覆我們的直覺
案例一:
案例二:
案例三:
個人對js閉包的心得見解