如果在函數內部生命函數inner,然後在函數外部調用inner,這個過程即產生了一個閉包。
閉包的用途:
1、匿名自執行函數,類似:click(function(){})。
2、緩存。
3、實現封裝。閉包的的一個重要用途就是實現面向對象中的對象。傳統的對象語言都提供類的模板機制,這樣不同的對象就擁有了獨立的成員和狀態,互不干涉。
雖然JavaScript沒有這種機制,但是我們可以使用閉包實現該機制,如下程序:
//JavaScript是基於對象而非面向對象的,若想實現面向對象,則需要使用閉包
function Person()
{
var name='default';
return {
getName:function()
{
return name;
},
setName:function(newName)
{
name=newName;
}
};
};
var jake=Person();
alert(jake.getName());
jake.setName('jake');
alert(jake.getName());
var jay=Person();
alert(jay.getName());
jay.setName('jay');
alert(jay.getName());
應該注意的問題:
1、內存泄漏,JavaScript解釋器都具備垃圾回收機制,一般採用的是引用計數的形式,如果一個對象的引用計數爲0,則垃圾回收器會將其回收,這個過程是自動的。
但是有了閉包後,變量的應用將變的比較複雜,因爲局部變量肯能會在某個時刻被外部應用,如果再出現嵌套引用等情況,則會出現無法回收的泄漏。
2、上下文引用this,它表示的是調用對象的引用,而在閉包中,最容易出現錯誤的地方就是誤用this。雖然閉包可以引用局部變量,但是涉及到this的時候,情況就不對了,
如下例:
//閉包中this變量的使用
function aa()
{
var obj=document.getElementById('name');
this.value='1000';//此處的this表示調用的對象
obj.οnclick=function()
{
alert("觸發該事件的對象this:"+this.value);//此處的this其實是本方法的觸發對象obj,而並非上一句中的this,故其值也非1000
};
//解決閉包的局部this引用問題
var self=this;
obj.οnmοuseοver=function()
{
alert("局部變量的this:"+self.value);
};
}
aa();//如果在這裏執行調用對象就是window
alert(window.value);