js閉包,阮老師說:‘閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。由于在Javascript語言中,只有函數(shù)內(nèi)部的子函數(shù)才能讀取局部變量,因此可以把閉包簡單理解成"定義在一個函數(shù)內(nèi)部的函數(shù)"。所以,在本質(zhì)上,閉包就是將函數(shù)內(nèi)部和函數(shù)外部連接起來的一座橋梁。’ 這里可能要先去理解一下全局 變量和局部變量,這里先不做過多的解釋!
接下來通過幾個例子,談一下對比包的理解以及各種閉包的寫法,下面的例子可能不夠?qū)I(yè),但是對于閉包的理解個人認(rèn)為還是有很大的幫助的!
<b>例子1:</b>
function a(){
var b = 1;
return function c(){
console.log(b)
}
}
a()(); //1
這個函數(shù)調(diào)用時,a()(),有兩個括號,第一個是調(diào)用a函數(shù),第二個是執(zhí)行c函數(shù)。 如果單獨(dú)執(zhí)行a();返回的就是c函數(shù)的函數(shù)體,這里就是把c函數(shù),緩存了一下,并沒有立即執(zhí)行!
<b>例子2:</b>
function a(){
return function(){
console.log(0)
}
}
a()(); //0
這種寫法,和上面一種寫法差不多,但是緩存的時候是匿名函數(shù),但是調(diào)用的方法是相同的!
<b>例子3:</b>
function a() {
var b = 1;
function c() {
alert(b);
}
return c;
}
var d = a();
d(); // 1
分析一下例子3,應(yīng)該可以看出c函數(shù)是一個閉包的形式,一個函數(shù)里面嵌套了另外一個函數(shù),被嵌套的函數(shù)被緩存了,也就是c函數(shù),但是此處的寫法略有不同,var d = a(); d();等同于a()();這里只是進(jìn)行了一次緩存,這樣就好理解了;
還有要注意的是:這段代碼有兩個特點(diǎn):
1、函數(shù)c嵌套在函數(shù)a內(nèi)部;
2、函數(shù)a返回函數(shù)c。
<b>例子4:</b>
var name = "The Window";
var object = {
name: "My Object",
getNameFunc: function() {
return function() {
return this.name;
};
}
};
alert(object.getNameFunc()()); //The Window
解釋一下,其實(shí)這塊很簡單,getNameFunc()第一次執(zhí)行時,如果在里面打印出this的話,這個this指向的是object,就返回了function() {return this.name;};,當(dāng)getNameFunc()()執(zhí)行時,就是執(zhí)行function() {return this.name};這樣一句話,這里的this指向的就是window了,所以最后的結(jié)果就是The Window了;
<b>例子5:</b>
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
}
};
alert(object.getNameFunc()()); //My Object
這個例子的話,和上面的相比,多了var that = this;
,然后返回的是that.name;
;參考上面的解釋,很明顯可以看出,因?yàn)関ar that = this, 返回的that.name,改變了this的指向,that指向的就是object了,所以最后的結(jié)果就是My Object了;
使用閉包的注意點(diǎn):
1)由于閉包會使得函數(shù)中的變量都被保存在內(nèi)存中,內(nèi)存消耗很大,所以不能濫用閉包,否則會造成網(wǎng)頁的性能問題,在IE中可能導(dǎo)致內(nèi)存泄露。解決方法是,在退出函數(shù)之前,將不使用的局部變量全部刪除。
2)閉包會在父函數(shù)外部,改變父函數(shù)內(nèi)部變量的值。所以,如果你把父函數(shù)當(dāng)作對象(object)使用,把閉包當(dāng)作它的公用方法(Public Method),把內(nèi)部變量當(dāng)作它的私有屬性(private value),這時一定要小心,不要隨便改變父函數(shù)內(nèi)部變量的值。
如果理解這些,我覺著閉包也就八九不離十了!