03 JS 閉包

1.概念

閉包是指有權訪問另一個函數(shù)作用域中的變量的函數(shù)钉凌。創(chuàng)建閉包的常見方式建钥,就是在一個函數(shù)內(nèi)部創(chuàng)建另一個函數(shù)选调。

2.示例說明

有關如何創(chuàng)建作用域鏈以及作用域鏈有什么作用的細節(jié)骤公,對徹底理解閉包至關重要堕义。

// 代碼示例 1
function createComparisonFunction(propertyName) {
    return function(object1, object2) {
        let value1 = object1[propertyName];
        let value2 = object2[propertyName];
        
        if(value1 < value2) {
            return -1;
        } else if(value1 > value2) {
            return 1;
        } else {
            return 0;
        }
    }
}

// 創(chuàng)建函數(shù)
let compareNames = createComparisonFunction('name');
// undefined
// 調(diào)用函數(shù)
let result = compareNames({name: 'Zhang'}, {name: 'Li'});

// 調(diào)用函數(shù)
let out = compareNames({name: 'Zhang'}, {name: 'Li'});
// undefined
out;
// 1

分析上述示例 1 代碼:

在匿名函數(shù)從 createComparisonFunction() 函數(shù)中被返回后坏瞄,它的作用域鏈被初始化為包含 createComparisonFunction() 函數(shù)的活動對象和全局變量對象桂对。createComparisonFunction() 函數(shù)在執(zhí)行完畢后,其活動對象也不會被銷毀鸠匀,因為匿名函數(shù)的作用域鏈仍然在引用這個活動對象蕉斜。換句話說,當 createComparisonFunction() 函數(shù)返回后缀棍,其執(zhí)行環(huán)境的作用域鏈會被銷毀宅此,但它的活動對象仍然會留在內(nèi)存中,直到匿名函數(shù)被銷毀后爬范,createComparisonFunction() 的活動對象才會被銷毀父腕。

閉包

由于閉包會攜帶包含其它的函數(shù)的作用域,因此會比其它函數(shù)占用更多的內(nèi)存青瀑。 慎重使用閉包璧亮。

3.閉包與變量

作用域鏈的這種配置機制引出了一個值得注意的副作用,即閉包只能取得包含函數(shù)中任何變量的最后一個值斥难。閉包所保存的是整個變量對象枝嘶,而不是某個特殊的變量。

// 代碼示例 2
function createFunction() {
    let result = new Array();

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

上述代碼示例 2 中哑诊,每個匿名函數(shù)的作用域鏈中都保存著 createFunction() 函數(shù)的活動對象群扶,所以它們引用的都是同一個 i。當 createFunction() 函數(shù)返回后镀裤,變量 i 的值是 10穷当,而每個函數(shù)都引用著保存變量 i 的同一個變量對象,每個函數(shù)內(nèi)部 i 的值都是 10淹禾。

// 代碼示例 3
function createFunction() {
    let result = new Array();

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

代碼示例 3 中,通過創(chuàng)建另一個匿名函數(shù)強制讓閉包的行為符合預期茴扁。在調(diào)用每個匿名函數(shù)時铃岔,我們傳入了變量 i,由于函數(shù)參數(shù)是按值傳遞的,所以就會將變量 i 的當前值復制給參數(shù) num毁习。而這個匿名函數(shù)內(nèi)部智嚷,又創(chuàng)建并返回了 num 的閉包。這樣一來纺且, result 數(shù)組中的每個函數(shù)都有自己 num 變量的一個副本盏道,因此可以返回各自不同的副本。

總結(jié)

閉包载碌,就是在一個函數(shù)內(nèi)部創(chuàng)建另一個函數(shù)猜嘱。里面函數(shù)的作用域鏈中引用了外部函數(shù)的活動對象,外部函數(shù)調(diào)用執(zhí)行完成時嫁艇,外部函數(shù)的作用域鏈會銷毀朗伶,而因為里面函數(shù)的作用域鏈中引用了外部函數(shù)的活動對象,只有在里面函數(shù)的執(zhí)行環(huán)境銷毀后步咪,外部函數(shù)的活動對象才你銷毀论皆。使用過多閉包會使內(nèi)存占用過多。

對于閉包的情況猾漫,閉包函數(shù)只有獲取包含函數(shù)中任何變量的最后一個值点晴。我們可以通過在匿名函數(shù)再次將閉包函數(shù)包裹起來,而閉包參數(shù)的引用通過匿名函數(shù)引用包含函數(shù)的值傳遞給參數(shù)悯周。

注:文章參考總結(jié)自 《JavaScript 高級程序設計》(第 3 版)[美] Nicholas C.Zakas 著 第 178 頁粒督。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嚣艇,一起剝皮案震驚了整個濱河市邪驮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌剩岳,老刑警劉巖捐康,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仇矾,死亡現(xiàn)場離奇詭異,居然都是意外死亡解总,警方通過查閱死者的電腦和手機贮匕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來花枫,“玉大人刻盐,你說我怎么就攤上這事±秃玻” “怎么了敦锌?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長佳簸。 經(jīng)常有香客問我乙墙,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任听想,我火速辦了婚禮腥刹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘汉买。我一直安慰自己衔峰,他們只是感情好,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布蛙粘。 她就那樣靜靜地躺著垫卤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪组题。 梳的紋絲不亂的頭發(fā)上葫男,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天,我揣著相機與錄音崔列,去河邊找鬼梢褐。 笑死,一個胖子當著我的面吹牛赵讯,可吹牛的內(nèi)容都是我干的盈咳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼边翼,長吁一口氣:“原來是場噩夢啊……” “哼鱼响!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起组底,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤丈积,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后债鸡,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體江滨,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年厌均,在試婚紗的時候發(fā)現(xiàn)自己被綠了唬滑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡棺弊,死狀恐怖晶密,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情模她,我是刑警寧澤稻艰,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站侈净,受9級特大地震影響连锯,放射性物質(zhì)發(fā)生泄漏归苍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一运怖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧夏伊,春花似錦摇展、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至鲁森,卻和暖如春祟滴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背歌溉。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工垄懂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人痛垛。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓草慧,卻偏偏與公主長得像,于是被迫代替她去往敵國和親匙头。 傳聞我的和親對象是個殘疾皇子漫谷,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355

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