什麼是閉包及閉包的優缺點
1、什麼是作用域鏈?
在理解閉包以前.最好能先理解一下作用域鏈的含義,簡單來說,作用域鏈就是函式在定義的時候建立的,用於尋找使用到的變數的值的一個索引,而他內部的規則是,把函式自身的本地變數放在最前面,把自身的父級函式中的變數放在其次,把再高一級函式中的變數放在更後面,以此類推直至全域性物件為止.當函式中需要查詢一個變數的值的時候,js直譯器會去作用域鏈去查詢,從最前面的本地變數中先找,如果沒有找到對應的變數,則到下一級的鏈上找,一旦找到了變數,則不再繼續.如果找到最後也沒找到需要的變數,則直譯器返回undefined.
2、Js的記憶體回收機制
瞭解了作用域鏈,我們再來看看js的記憶體回收機制
3、什麼是閉包
閉包是有權訪問另一個函式作用域的變數的函式。
簡單的說,Javascript允許使用內部函式---即函式定義和函式表示式位於另一個函式的函式體內。而且,這些內部函式可以訪問它們所在的外部函式中宣告的所有區域性變數、引數和宣告的其他內部函式。當其中一個這樣的內部函式在包含它們的外部函式之外被呼叫時,就會形成閉包。
4、閉包的主要作用
閉包可以用在許多地方。它的最大用處有兩個:一個是前面提到的可以讀取函式內部的變數,另一個就是讓這些變數的值始終保持在記憶體中。
5、閉包與this物件
在閉包中使用this物件可能會導致一些問題,因為匿名函式的執行具有全域性性,因此其this物件通常指window
把外部作用域的this物件儲存在一個閉包能夠訪問的變數裡面,就可以讓閉包訪問物件了,
6、閉包與記憶體洩漏
具體來說,如果閉包的作用域中儲存著一個html元素,那麼就意味著元素無法被銷燬。
以上程式碼建立了一個作為element元素事件處理程式的閉包,而這個閉包則又建立了一個迴圈引用。由於匿名函式儲存了一個對assignHandler()的活動物件的引用,因此會導致無法減少element的引用數。只有匿名函式存在,element的引用數至少也是1,因此他所佔用的記憶體就不會被回收。
通過寫程式碼來解決內部不能回收問題:
以上程式碼,實現閉包不直接引用element,包含函式的活動物件中也仍然會儲存一個引用。因此,有必要把element的變數設定為null,這樣就可以回收其佔用的記憶體。
7、使用閉包的注意點
1)由於閉包會使得函式中的變數都被儲存在記憶體中,記憶體消耗很大,所以不能濫用閉包,否則會造成網頁的效能問題,在IE中可能導致記憶體洩露。解決方法是,在退出函式之前,將不使用的區域性變數全部刪除。
2)閉包會在父函式外部,改變父函式內部變數的值。所以,如果你把父函式當作物件(object)使用,把閉包當作它的公用方法(Public Method),把內部變數當作它的私有屬性(private value),這時一定要小心,不要隨便改變父函式內部變數的值。