**
個人部落格開通啦!功能正在逐漸完善中,大家可以通路http://www.codeliu.com
閉包是JavaScript中比較重要的一部分,也是比較難的一個知識點。在看了阮一峰老師的關于閉包的部落格後,感覺對閉包的了解更清晰了,有需要的同學不妨一看。
http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html#comment-text 這是阮一峰老師文章的部落格位址,下面我也做一個小小的總結,有興趣的可以看看。
1.變量的作用域
要了解閉包,首先我們要了解一下變量的作用域,分為全局變量和局部變量。全局變量,就是在任何一個地方都可以被通路到,局部變量,就是隻能在一定範圍内被通路。
var n=1225;
function f1(){
console.log(n);
}
f1(); //1225
上面定義的n就是全局變量,在函數内部也可以通路到。
function f1(){
var n=1225;
console.log(n);
}
f1(); //1225
console.log(n); //undefined
上面定義的n就是局部變量,函數調用後會立即銷毀,所有再通路n就無法取得它的值了。
但注意在函數裡的定義的變量前面一定要加var,否則就變成全局變量了。看下面的代碼
function f1(){
n=1225;
}
f1();
n; //1225
上面的代碼中定義n時沒有加var,這樣n就是全局變量,在外面依然可以通路n。
2. 如何在外部通路函數内部的變量?
在正常情況下,因為在函數内部定義的變量都是局部變量,是以要在外部通路内部的變量,似乎是行不通的。
function f1(){
var n=1225;
function f2(){
console.log(n);
}
return f2;
}
var result=f1();
result(); //1225
在上面的代碼中,通過在函數内部定義另一個函數來擷取n的值,這就是閉包。
3.什麼是閉包?
在上面的例子中,f2就是閉包。閉包是什麼?我認為閉包就是能夠讀取其他函數内部變量的函數,是連接配接外部和内部的橋梁。
在JavaScript語言中,隻有在函數内部的子函數才能讀取局部變量,是以可以把閉包了解為“定義在函數内部的函數”。
4.閉包的作用
1.能夠讀取函數内部的值
前面的代碼已經展示了。
2.能讓變量的值始終儲存在記憶體中,不會被立即銷毀。
前面我們說過,在函數内部定義的局部變量,在函數執行後,會被立即銷毀,那閉包怎麼讓變量的值不被銷毀呢?
function f1(){
var n=1225;
add=function(){
n++;
}
function f2(){
console.log(n);
}
return f2;
}
var result=f1();
result(); //1225
add();
result(); //1226
在上面的代碼中,第一個result()執行後,列印出1225,執行add()後,再執行result()後,列印出1226,說明n沒有被立即銷毀。
result被定義為全局變量,f1是f2的父函數,而f2指派給result,成為全局變量,f2的存在又依賴于f1,是以f1也始終存在于記憶體中,不會再調用結束後,被垃圾回收機制(garbage collection)回收。
這段代碼中另一個值得注意的地方,就是”nAdd=function(){n+=1}”這一行,首先在nAdd前面沒有使用var關鍵字,是以nAdd是一個全局變量,而不是局部變量。其次,nAdd的值是一個匿名函數(anonymous function),而這個匿名函數本身也是一個閉包,是以nAdd相當于是一個setter,可以在函數外部對函數内部的局部變量進行操作。