關於JS閉包的理解
一、概念的理解
閉包(closure)是Javascript語言的一個難點,也是它的特色,很多高階應用都要依靠閉包實現。 這個概念看起來稍顯複雜,我之前也接觸過離散數學上閉包的概念,當時就不咋懂。(博主研究生專業研究的是偏數學的東西。。。)在JS紅寶書上是這樣定義的:“閉包是指有權訪問另一個函式作用域中的變數的函式。” 由於JS中變數的分為全域性變數和區域性變數,因此作用域也不同,在函式外部是無法讀取函式內的區域性變數。那麼閉包定義在函式內部,函式內部的變數相當於是它的全域性變數,自然可以訪問。例如:
function f1(){
n=100;
function f2( ){
alert(n);
}
return f2;
}
var result=f1();
result(); // 100
程式碼中的f2函式就是一個閉包。結合一些部落格和資料,我的理解是,閉包就是能夠讀取其他函式內部變數的函式。本質上,閉包就是將函式內部和函式外部連線起來的一座橋樑。
二、閉包的用途
閉包的最大用途有兩個,一個是之前提到的可以讀取函式內部的變數,另一個就是讓這些變數的值始終保持在記憶體中。先看下面一段程式碼:
function f1() {
var n = 99;
Add = function() {
n += 1
}
function f2() {
alert(n);
}
return f2;
}
var result = f1();
result(); // 99
Add();
result(); // 100
在這段程式碼中,result即閉包f2函式。它一共運行了兩次,第一次的值是99,第二次的值是100。這說明函式f1中的區域性變數n一直儲存在記憶體中,並沒有在f1呼叫後被自動清除。 沒有被垃圾回收的原因就在於f1是f2的父函式,n對於f2是一個全域性變數,這導致f2始終在記憶體中,而f2的存在也依賴於f1,因此f1也始終在記憶體中,不會在呼叫結束後,被垃圾回收機制回收。 另外,不知道注意到沒有,就是“Add=function(){n+=1}”這一行,由於在Add前面沒有使用var關鍵字,使 Add是一個全域性變數,而不是區域性變數。並且Add的值是一個匿名函式,這個匿名函式本身也是一個閉包,所以Add可以在函式外部對函式內部的區域性變數進行操作。
本文只是簡單地介紹一下對閉包的理解,很多使用之處還需要多加註意和思考。學無止境,多多鑽研哈~