淺談對JavaScript閉包的理解

首先我們先來看一段代碼

淺談對JavaScript閉包的理解

從上面的代碼可以看出js都有一個特性特性,局部方法可以訪問外部父類方法的屬性,也就是說,子類或子方法可以訪問父類的資源。

我們再來看一段代碼

淺談對JavaScript閉包的理解

為什麼我們打印出來的是undefined?因為子方法的變量作用域僅僅是子方法的範圍,外部是無法獲取到的。那麼js中是如何獲取字方法裡面的值呢?我們來看下面的代碼

淺談對JavaScript閉包的理解

淺談對JavaScript閉包的理解

在外部無法獲取到funOne內部的局部變量,但是funOne內部的局部方法funTwo卻可以獲取到,因此 返回一個funTwo的引用,這樣在外部通過這個funTwo就可以獲取到funOne的內部變量。而這個方法內的局部方法funTwo就叫做閉包。簡單的總結下有權訪問另一個函數作用域內變量的函數都是閉包。

為什麼要用閉包

我們知道,js的每個函數都是一個個小黑屋,它可以獲取外界信息,但是外界卻無法直接看到裡面的內容。將變量 myname放進小黑屋裡,除了funOne函數之外,沒有其他辦法能接觸到變量myname,而且在函數funOne外定義同名的變量myname 也是互不影響的,這就是所謂的增強“封裝性”。

閉包的用途

閉包可以用在許多地方。它的最大用處有兩個,一個是前面說到的可以讀取函數內部的變量,另一個就是讓這些變量的值始終保持在內存中,不會在funOne調用後被自動清除。

為什麼會這樣呢?原因就在於funOne是funTwo的父函數,而funTwo被賦給了一個全局變量,這導致funTwo始終在內存中,而funTwo的存在依賴於funOne,因此funOne也始終在內存中,不會在調用結束後,被回收。好比一個餐廳,盤子總是有限的,所以服務員會去巡臺回收空盤子,但還裝著菜的盤子他怎麼敢收?

注意!!

(1) 由於閉包會使得函數中的變量都被保存在內存中,內存消耗很大,所以不能濫用閉包,否則會造成網頁的性能問題,在IE中可能導致內存洩露。解決方法是,在退出函數之前,將不使用的局部變量全部刪除。

(2) 閉包會在父函數外部,改變父函數內部變量的值。所以,,不要隨便改變父函數內部變量的值。

常見缺陷

函數帶()才是執行函數單純的一句 var myname =funOne; 是不會打印的,後面接一myname (); 才會執行函數內部的代碼。

總結

其實很多的方法都是給予閉包像redux 中的store就是用閉包和觀察者模式來完成的,閉包應用的地方很多也很廣泛,可以和很多的東西搭配,所以我們的路還有很長,這只是一個開始


分享到:


相關文章: