一蹬音、閉包的含義
官方對(duì)閉包的解釋?zhuān)阂粋€(gè)擁有許多變量和綁定了這些變量的環(huán)境的表達(dá)式(通常是一個(gè)函數(shù)),因而這些變量也是該表達(dá)式的一部分休玩。
二著淆、閉包的特點(diǎn):
- 作為一個(gè)函數(shù)變量的一個(gè)引用,當(dāng)函數(shù)返回時(shí)拴疤,其處于激活狀態(tài)永部。
- 一個(gè)閉包就是當(dāng)一個(gè)函數(shù)返回時(shí),一個(gè)沒(méi)有釋放資源的棧區(qū)遥赚。
簡(jiǎn)單的閉包如下:
function f1(){
var n = 100;
return function f2(){
alert(++n);
}
}
函數(shù)執(zhí)行時(shí)創(chuàng)建了一個(gè)內(nèi)部函數(shù)扬舒,這個(gè)內(nèi)部函數(shù)作為返回值,或以某種方式保留下來(lái)(屬性)凫佛,之后才會(huì)調(diào)用讲坎,這就會(huì)形成了閉包。通俗來(lái)講愧薛,JS所有的function都是一個(gè)閉包晨炕。
三、用途場(chǎng)景
匿名自執(zhí)行函數(shù)
我們創(chuàng)建了一個(gè)匿名的函數(shù)毫炉,并立即執(zhí)行它瓮栗,由于外部無(wú)法引用它內(nèi)部的變量,因此在函數(shù)執(zhí)行完后會(huì)立刻釋放資源瞄勾,關(guān)鍵是不污染全局對(duì)象费奸。
代碼如下:
(function() {
var days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
today = new Date(),
msg = 'Today is ' + days[today.getDay()] + ', ' + today.getDate();
alert(msg);
} ());-
結(jié)果緩存
我們開(kāi)發(fā)中會(huì)碰到很多情況,設(shè)想我們有一個(gè)處理過(guò)程很耗時(shí)的函數(shù)對(duì)象进陡,每次調(diào)用都會(huì)花費(fèi)很長(zhǎng)時(shí)間愿阐,那么我們就需要將計(jì)算出來(lái)的值存儲(chǔ)起來(lái),當(dāng)調(diào)用這個(gè)函數(shù)的時(shí)候趾疚,首先在緩存中查找缨历,如果找不到以蕴,則進(jìn)行計(jì)算,然后更新緩存并返回值辛孵,如果找到了丛肮,直接返回查找到的值即可。閉包正是可以做到這一點(diǎn)魄缚,因?yàn)樗粫?huì)釋放外部的引用宝与,從而函數(shù)內(nèi)部的值可以得以保留。
var CachedSearchBox = (function(){
var cache = {},
count = [];
return {
attachSearchBox : function(dsid){
if(dsid in cache){//如果結(jié)果在緩存中
return cache[dsid];//直接返回緩存中的對(duì)象
}
var fsb = new uikit.webctrl.SearchBox(dsid);//新建
cache[dsid] = fsb;//更新緩存
if(count.length > 100){//保正緩存的大小<=100
delete cache[count.shift()];
}
return fsb;
},clearSearchBox : function(dsid){ if(dsid in cache){ cache[dsid].clearSelection(); } } }; })();
封裝
var person = function(){
//變量作用域?yàn)楹瘮?shù)內(nèi)部鲜滩,外部無(wú)法訪(fǎng)問(wèn)
var name = "default";
return {
getName : function(){
return name;
},
setName : function(newName){
name = newName;
}
}
}();-
實(shí)現(xiàn)類(lèi)和繼承
function Person(){
var name = "default";
return {
getName : function(){
return name;
},
setName : function(newName){
name = newName;
}
}
};var p = new Person(); p.setName("Tom"); alert(p.getName());//Tom var Jack = function(){}; //繼承自Person Jack.prototype = new Person(); //添加私有方法 Jack.prototype.Say = function(){ alert("Hello,my name is Jack"); }; var j = new Jack(); j.setName("Jack"); j.Say(); alert(j.getName());//Jack
四伴鳖、優(yōu)缺點(diǎn)
- 優(yōu)點(diǎn)
1.可以讀取函數(shù)內(nèi)部的變量
2.可以讓這些局部變量保存在內(nèi)存中节值,實(shí)現(xiàn)變量數(shù)據(jù)共享徙硅。 - 缺點(diǎn)
1.由于閉包會(huì)使得函數(shù)中的變量都被保存在內(nèi)存中,內(nèi)存消耗很大搞疗,所以不能濫用閉包嗓蘑,否則會(huì)造成網(wǎng)頁(yè)的性能問(wèn)題,在IE中可能導(dǎo)致內(nèi)存泄露匿乃。解決方法是桩皿,在退出函數(shù)之前泄隔,將不使用的局部變量全部刪除。
2.閉包會(huì)在父函數(shù)外部,改變父函數(shù)內(nèi)部變量的值。所以,如果你把父函數(shù)當(dāng)作對(duì)象(object)使用戚揭,把閉包當(dāng)作它的公用方法(Public Method)蔬啡,把內(nèi)部變量當(dāng)作它的私有屬性(private value),這時(shí)一定要小心,不要隨便改變父函數(shù)內(nèi)部變量的值辈毯。