一文瞭解JavaScript閉包函數
變量作用域
要理解JavaScript閉包,就要先理解JavaScript的變量作用域。
變量的作用域有兩種:全局的和局部的(全局變量和局部變量)
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()函數就是一個閉包函數。
閉包的概念
由於作用域原因,我們無法在函數外訪問函數裡面定義的變量,但有事我們又有這個需求,因此就出現瞭閉包的概念。
閉包是指有權訪問另一個函數作用域中的變量的函數。
在上面的例子中,內部函數f2就是一個閉包函數。
在本質上,閉包就是將函數內部和函數外部連接起來的橋梁。
閉包是一種保護私有變量的機制,在函數執行時形成私有的作用域,保護裡面的私有變量不受外界幹擾。
閉包的用途
(1)可以讀取父級作用域函數內部的變量;
(2)讓變量的值始終保存在內存中(讓局部變量變成全局變量),不被垃圾回收機制清除。
閉包的缺點
由於閉包會使函數中的變量都保存到內存中,垃圾回收機制不清理,內存消耗很大,所以不能濫用閉包,否則可能導致內存泄漏。
補充:
什麼是內存泄漏?
程序的運行都是需要內存的。隻要對內存提出要求,操作系統必須供給內存。
當應用程序中的一些代碼變量不再需要用到內存時,但是沒有被操作系統或者可用內存池回收,就說明它發生瞭內存泄漏。
即,當已經不再需要某塊內存時,這塊內存還存在著——內存泄漏
解決閉包引起的內存泄漏的問題:
在退出函數之前,將不使用的局部變量全部刪除。
例如:將當前變量的值設置為‘null’,當垃圾回收機制啟動時,會自動對這些值為‘null’的變量回收。
最後總結一下閉包的好處與壞處
好處
①保護函數內的變量安全 ,實現封裝,防止變量流入其他環境發生命名沖突
②在內存中維持一個變量,可以做緩存(但使用多瞭同時也是一項缺點,消耗內存)
③匿名自執行函數可以減少內存消耗
壞處
①其中一點上面已經有體現瞭,就是被引用的私有變量不能被銷毀,增大瞭內存消耗,造成內存泄漏,解決方法是可以在使用完變量後手動為它賦值為null;
②其次由於閉包涉及跨域訪問,所以會導致性能損失,我們可以通過把跨作用域變量存儲在局部變量中,然後直接訪問局部變量,來減輕對執行速度的影響
總結
到此這篇關於JavaScript閉包函數的文章就介紹到這瞭,更多相關JavaScript閉包函數內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- JavaScript的function函數詳細介紹
- 關於JavaScript回調函數的深入理解
- 初識JavaScript的基礎
- 詳解JavaScript錯誤捕獲
- 一篇文章帶你瞭解JavaScript-語句