【函數(shù)表達(dá)式】閉包

定義函數(shù)的方法:Function類型

匿名函數(shù)——function關(guān)鍵字后面沒有標(biāo)識(shí)符的函數(shù)萍摊。
閉包——有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù)养涮。

//創(chuàng)建閉包的方法:在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù)巧骚。
function createComparisonFunction(propertyName){
    return function (object1,object2) {
        var value1 = object1[propertyName];
        var value2 = object2[propertyName];
        if(value1<value2){
            return -1;
        }else if(value1>value2){
            return 1;
        }else{
            return 0;
        }
    }
}

一般來說速客,當(dāng)函數(shù)執(zhí)行完畢后迹淌,局部活動(dòng)對象就會(huì)被銷毀对妄,內(nèi)存中僅保存全局作用于(全局執(zhí)行環(huán)境的變量對象)湘今。但是,閉包的情況有所不同剪菱。

var compare = createComparisonFunction("name");
var result = compare({name:"Wonder"},{name:"Greg"});

上面代碼執(zhí)行時(shí),匿名函數(shù)從createComparisonFunction()中被返回后旗们,它的作用域鏈被初始化為包含createComparisonFunction()函數(shù)的活動(dòng)對象和全局變量對象。這樣构灸,匿名函數(shù)就可以訪問在createComparisonFunction()中定義的所有變量上渴。
更重要的是,createComparisonFunction()函數(shù)在執(zhí)行完畢后喜颁,其活動(dòng)對象也不會(huì)被銷毀,因?yàn)槟涿瘮?shù)的作用域鏈仍然在引用這個(gè)活動(dòng)對象洛巢。即當(dāng)createComparisonFunction()函數(shù)返回后,其執(zhí)行環(huán)境的作用域鏈會(huì)被銷毀稿茉,但它的活動(dòng)對象仍然會(huì)留在內(nèi)存中;直到匿名函數(shù)被銷毀后漓库,createComparisonFunction()的活動(dòng)隊(duì)想才會(huì)被銷毀。

//創(chuàng)建函數(shù)
var compare = createComparisonFunction("name");  
//調(diào)用函數(shù)
var result = compare({name:"Wonder"},{name:"Greg"});
//接觸對匿名函數(shù)的引用(以便釋放內(nèi)存
compare = null;

由于閉包會(huì)攜帶包含它的函數(shù)的作用域痢士,因此會(huì)比其他函數(shù)占用更多的內(nèi)存。過度使用閉包可能會(huì)導(dǎo)致內(nèi)存占用過多怠蹂。

閉包與變量

閉包只能取得包含函數(shù)中任何變量的最后一個(gè)值少态。

function createFunctions() {
    var result = new Array();

    for (var i = 0; i < 10; i++) {
        result[i] = function () {
            return i;
        };
    }
    return result;
}
var re = createFunctions();
alert(re[0]());             //10

這個(gè)函數(shù)會(huì)返回一個(gè)函數(shù)數(shù)組。表面上看彼妻,似乎每個(gè)函數(shù)都應(yīng)該返回自己的索引值,但實(shí)際上侨歉,每個(gè)函數(shù)都返回10。因?yàn)槊總€(gè)函數(shù)的作用域鏈中都保存著createFunctions()函數(shù)的活動(dòng)對象炮温,所以它們引用的都是同一個(gè)變量i。當(dāng)createFunctions()函數(shù)返回后茅特,變量i的值是10棋枕,此時(shí)每個(gè)函數(shù)都引用這保存變量i的同一個(gè)變量對象,所以在每個(gè)函數(shù)內(nèi)部i的值都是10重斑。

解決辦法:創(chuàng)建另一個(gè)匿名函數(shù)強(qiáng)制讓閉包的行為符合預(yù)期。

function createFunctions() {
    var result = new Array();

    for (var i = 0; i < 10; i++) {
        result[i] = function (num) {
            return function () {
                return num;
            };
        }(i);
    }
    return result;
}

var re = createFunctions();
alert(re[0]());

關(guān)于this對象

匿名函數(shù)的執(zhí)行環(huán)節(jié)具有全局性窥浪,因此this對象通常指向window。

var name = "window";
 var object = {
     name:"object",
     getNameFunc: function () {
         return function () {
             return this.name;
         }
     }
 }

 alert(object.getNameFunc()());  //(非嚴(yán)格模式下)window

每個(gè)函數(shù)在被調(diào)用時(shí)都會(huì)自動(dòng)取得兩個(gè)特殊變量:this和arguments假颇。內(nèi)部函數(shù)在搜索這兩個(gè)變量時(shí)骨稿,只會(huì)搜索到其活動(dòng)對象為止笨鸡,因此永遠(yuǎn)不可能直接訪問外部函數(shù)中的這兩個(gè)變量。
解決方案:把外部作用域中的this對象保存在一個(gè)閉包能夠訪問到的變量里哥桥,就可以讓閉包訪問該對象了。

var name = "window";
var object = {
    name:"object",
    getNameFunc: function () {
        var that = this;
        return function () {
            return that.name;
        }
    }
}

alert(object.getNameFunc()()); //object

內(nèi)存泄漏

IE9之前的版本對JScript對象和COM對象使用不同的垃圾回收例程激涤,因此閉包在IE的這些版本中會(huì)導(dǎo)致一些特殊的問題。

如果閉包的作用域鏈中保存著一個(gè)HTML元素倦踢,那么就意味著該元素將無法被銷毀。

function assignHandler(){
     var element = document.getElementById("someElement");
     element.onclick = function(){
         alert(element.id);
     }
 }

解決方案:

function assignHandler(){
    var element = document.getElementById("someElement");
    var id = element.id;
    element.onclick = function(){
        alert(id);
    }
    element = null;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末犁嗅,一起剝皮案震驚了整個(gè)濱河市般贼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌哼蛆,老刑警劉巖蕊梧,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腮介,死亡現(xiàn)場離奇詭異,居然都是意外死亡叠洗,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進(jìn)店門十艾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來腾节,“玉大人,你說我怎么就攤上這事案腺。” “怎么了劈榨?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長拷姿。 經(jīng)常有香客問我,道長跌前,這世上最難降的妖魔是什么陡舅? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮灾炭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蜈出。我一直安慰自己涛酗,他們只是感情好铡原,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布燕刻。 她就那樣靜靜地躺著,像睡著了一般卵洗。 火紅的嫁衣襯著肌膚如雪弥咪。 梳的紋絲不亂的頭發(fā)上过蹂,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天酷勺,我揣著相機(jī)與錄音,去河邊找鬼脆诉。 笑死坦报,一個(gè)胖子當(dāng)著我的面吹牛库说,可吹牛的內(nèi)容都是我干的片择。 我是一名探鬼主播,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼啰挪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了亡呵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤下硕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后梭姓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嫩码,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年铡恕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片探熔。...
    茶點(diǎn)故事閱讀 39,953評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡千劈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出墙牌,到底是詐尸還是另有隱情,我是刑警寧澤喜滨,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站棒口,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏无牵。R本人自食惡果不足惜厂抖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧谭溉,春花似錦、人聲如沸扮念。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谈为。三九已至踢关,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間签舞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工吠架, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人傍药。 一個(gè)月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓魂仍,卻偏偏與公主長得像拐辽,于是被迫代替她去往敵國和親擦酌。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 定義函數(shù)的方式有兩種:函數(shù)聲明和函數(shù)表達(dá)式睁搭。 函數(shù)聲明的一個(gè)重要特征就是函數(shù)聲明提升笼平,意思是在執(zhí)行代碼前會(huì)先讀取函...
    oWSQo閱讀 665評論 0 0
  • 閉包 閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù)。創(chuàng)建閉包的常見方式就是在一個(gè)函數(shù)的內(nèi)部創(chuàng)建另一個(gè)函數(shù)寓调。 當(dāng)某...
    胖胖冰閱讀 313評論 0 1
  • 函數(shù) 理解參數(shù) JavaScript函數(shù)不介意傳遞多少個(gè)參數(shù),也不介意傳遞參數(shù)的數(shù)據(jù)類型鸠珠。也就是說函數(shù)定義接受多少...
    TaoGeNet閱讀 215評論 0 2
  • 1? 為什么疲憊總是懶惰的最好借口,為什么輕松會(huì)成為快樂的理由渐排?既然喜歡跋山涉水,為什么還要在意旅途的艱難驯耻? ...
    守望幸福_a029閱讀 314評論 0 2
  • THE NOW HABBIT 當(dāng)初高中的時(shí)候艾力老師推薦的書,推薦了很多次霎迫,說非常好非常好,于是抱著看一看也好的心...
    彭銘杰閱讀 789評論 0 3