一文了解JavaScript閉包函式
目錄
- 變數作用域
- 閉包的概念
- 閉包的用途
- 閉包的缺點
- 最後總結一下閉包的好處與壞處
- 總結
變數作用域tlVSin
要理解閉包,就要先理解Script的變數作用域。
變數的作用域有兩種:全域性的和區域性的(全域性變數和區域性變數)
JavaScript中,在函式內部可以直接讀取到全域性變數。
var n=10 function fn(){ alert(n) } fn() //10
而在函式外部無法讀取到函式內部的變數。
function fn(){ var n=10; } fn() alert(n) //n is not defined 函式外部無法讀取到函式內部的n
注意:函式內部使用var宣告變數的時候,這個變數是區域性變數,如果不使用var,那麼這個變數就是一個全域性變數。
例如:
function fn(){ n=10; } fn() alert(n) //10
另外,函式的引數也是區域性性的,只在函式內部起作用。
在正常情況下,我們是無法得到函式內部的區域性變數的,只有變通方法才可以——在函式內部再宣告一個函式。
function f1(){ var n=10; function f2(){ alert(n) } }
f2函式可以得到f1函式內的所有區域性變數,但是f1函式卻無法得到f2函式內部的區域性變數——JavaScript語言特有的“鏈式作用域”結構。(即子物件會一級一級地向上尋找所有父物件的變數),所以,父物件的所有變數,對於子物件都是可見的。
f2函式可以獲取到父級函式f1的區域性變數,那麼如果把f2()函式返回,在函式f1外部就可以訪問到f1()函式內部的變量了。
例如:
function f1(){ var n=10; function f2(){ alert(n) } return f2() } f1() //頁面彈出10
例子中的f2()函式就是一個閉包函式。
閉包的概念
由於作用域原因,我們無法在函式外訪問函式裡面定義的變數,但有事我們又有這個需求,因此就出http://www.cppcns.com現了閉包的概念。
閉包是指有權訪問另一個函式作用域中的變數的函式。
在上面的例子中,內部函式f2就是一個閉包函式。
在本質上,閉包就是將函式內部和函式外部連線起來的橋樑。
閉包是一種保護私有變數的機制,在函式執行時形成私有的作用域,保護裡面的私有變數不受外界干擾。
閉包的用途
(1)可以讀取父級作用域函式內部的變數;
(2)讓變數的值始終儲存在記憶體中(讓區域性變數變成全域性變數),不被垃圾回收機制清除。
閉包的缺點
由於閉包會使函式中的變數都儲存到記憶體中,垃圾回收機制不清理,記憶體消耗很大,所以不能濫用閉包,否則可能導致記憶體洩漏。
補充:
什麼是記憶體洩漏?
程式的執行都是需要記憶體的。只要對記憶體提出要求,必須供給http://www.cppcns.com記憶體。
當應用程式中的一些程式碼變數不再需要用到記憶體時,但是沒有被作業系統或者可用記憶體池回收,就說明它發生了記憶體洩漏。
即,當已經不再需要某塊記憶體時,這塊記憶體還存在著——記憶體洩漏
解決閉包引起的記憶體洩漏的問題:
在退出函式之前,將不使用的區域性變數全部刪除。
例如:將當前變數的值設定為‘null',當垃圾回收機制啟動時,會自動對這些值為‘null'的變量回收。
最後總結一下閉包的好處與壞處
好處
①保護函式內的變數安全 ,實現封裝,防止變數流入其他環境發生命名衝突
②在記憶體中維持一個變數,可以做快取(但使用多了同時也是一項缺點,消耗記憶體)
③匿名自執行函式可以減少記憶體消耗
壞處
①其中一點上面已經有體現了,就是被引用的私有變數不能被銷tlVSin毀,增大了記憶體消耗,造成記憶體洩漏,解決方法是可以在使用完變數後手動為它賦值為null;
②其次由於閉包涉及跨域訪問,所以會導致效能損失,我們可以通過把跨作用域變數儲存在區域性變數中,然後直接訪問區域性變數,來減輕對執行速度的影響
總結
到此這篇關於JavaScript閉包函式的文章就介紹到這了,更多相關JavaScript閉包函式內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!