簡(jiǎn)單的聊一下閉包

js中的閉包

閉包是學(xué)習(xí)js中永遠(yuǎn)也繞不過(guò)去的一個(gè)坎叹洲,那么柠硕,今天我們就去一段簡(jiǎn)單的代碼開始聊一聊閉包

什么是閉包

這個(gè)概念性的東西翻譯有很多種,純官方的翻譯比較晦澀難懂运提,我們把它理解成一個(gè)比較特殊的函數(shù)就行蝗柔。按照網(wǎng)上的說(shuō)法來(lái)說(shuō)就是:

「函數(shù)」和「函數(shù)內(nèi)部能訪問(wèn)到的變量」(也叫環(huán)境)的總和,就是一個(gè)閉包民泵。

  function close() {
        var n=999;
        var getNumber=function () {
            return n;
        };
        return getNumber;
    }

在close函數(shù)里面有一個(gè)getNumber方法癣丧,通過(guò)getNumber方法可以訪問(wèn)到函數(shù)的內(nèi)部變量。

閉包的特性

  • 能夠讀取函數(shù)內(nèi)部的變量
  • 能讓這些變量的值始終保持在內(nèi)存中

第一點(diǎn)很好理解栈妆,我們平時(shí)可能在不知不覺(jué)中就使用了閉包的這個(gè)特性胁编,而第二點(diǎn)雖然用的不多,但是在面試中經(jīng)常遇到鳞尔。首先我們先看一段代碼:

 function f1() {
        var n=999;
        nAdd=function () {
            n++;
        };
        function f2() {
            console.log(n);
        }
        return f2;
    }
    var result=f1();
    result();//999
    nAdd();
    result();//1000

為什么第二次執(zhí)行后打印的結(jié)果是1000赠涮,而不是999击你,因?yàn)閚被保存下來(lái)了,并沒(méi)有被內(nèi)存回收機(jī)制回收营袜。

為什么每有被回收洛史?因?yàn)閒1是f2的父函數(shù)央勒,而f2被賦給了一個(gè)全局變量寺滚,這導(dǎo)致f2始終在內(nèi)存中斑鼻,而f2的存在依賴于f1,因此f1也始終在內(nèi)存中萤彩,不會(huì)在調(diào)用結(jié)束后粪滤,被垃圾回收機(jī)制(garbage collection)回收。

面試題解讀

這是一個(gè)很常見的閉包面試題:

    var result=[];
    function foo(){
        var i= 0;
        for (;i<3;i=i+1){
            result[i]=function () {
                alert(i);
            }
        }
    }         
    foo();
    result[0](); // 3
    result[1](); // 3
    result[2](); // 3

運(yùn)行結(jié)果為什么是3乒疏,我簡(jiǎn)單的重現(xiàn)一下代碼運(yùn)行的過(guò)程额衙,

i=0;
result[0]=function(){alert(i)};
i=1;
result[1]=function(){alert(i)};
i=2;
result[2]=function(){alert(i)};

運(yùn)行的時(shí)候在function內(nèi)部放的是一個(gè)變量i,只有被執(zhí)行的時(shí)候才會(huì)給這個(gè)i賦值怕吴。當(dāng)執(zhí)行result[0]的時(shí)候窍侧,里面的變量i因?yàn)樵诋?dāng)前作用域下并沒(méi)有被定義,所以向它的父級(jí)去找转绷,此時(shí)for循環(huán)已經(jīng)執(zhí)行完畢伟件,i的值是3,所以彈出的都是3议经。為什么i保存下來(lái)了斧账,因?yàn)閞esult函數(shù)依賴于foo函數(shù),所以foo一直在內(nèi)存中煞肾,i變量也沒(méi)有被內(nèi)存回收機(jī)制回收咧织。
那么如何實(shí)現(xiàn)彈出的是0,1籍救,2呢习绢?
利用之前提到的閉包就可以了,代碼如下:

    var result=[];
    function foo(){
        var i= 0;
        for (;i<3;i=i+1){
            (function () {
                var index=i;
                result[i]=function () {
                    alert(index);
                }
            })()
        }
    }
    foo();
    result[0](); // 0
    result[1](); // 1
    result[2](); // 2

利用立即執(zhí)行函數(shù)(IIF)蝙昙,我們可以創(chuàng)建一個(gè)閉包闪萄,在這個(gè)IIF內(nèi)部,我們使用index將i給保存下來(lái)了奇颠。具體執(zhí)行過(guò)程如下:

i=0;
(function () {
    var index=0;
    result[0]=function () {
        alert(index);
    }
})()
i=1;
(function () {
    var index=1;
    result[1]=function () {
        alert(index);
    }
})()
i=2;
(function () {
    var index=2;
    result[2]=function () {
        alert(index);
    }
})()

因?yàn)檫@些語(yǔ)句都放在IIF中败去,所以都有各自的作用域,index并不會(huì)重復(fù)烈拒。就像下方的代碼:

var sayHi=function(){
    var words="hi"
}
var sayHello=function(){
    var words="hello"
}

兩個(gè)方法中雖然都有words這個(gè)變量圆裕,但是因?yàn)樵诓煌暮瘮?shù)中,都有各自的作用域荆几,所以互不干擾吓妆。

參考文獻(xiàn)

阮一峰:學(xué)習(xí)Javascript閉包(Closure)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市伴郁,隨后出現(xiàn)的幾起案子耿战,更是在濱河造成了極大的恐慌,老刑警劉巖焊傅,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件剂陡,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡狐胎,警方通過(guò)查閱死者的電腦和手機(jī)鸭栖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)握巢,“玉大人晕鹊,你說(shuō)我怎么就攤上這事。” “怎么了溅话?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵晓锻,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我飞几,道長(zhǎng)砚哆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任屑墨,我火速辦了婚禮躁锁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘卵史。我一直安慰自己战转,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布以躯。 她就那樣靜靜地躺著槐秧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪寸潦。 梳的紋絲不亂的頭發(fā)上色鸳,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音见转,去河邊找鬼命雀。 笑死,一個(gè)胖子當(dāng)著我的面吹牛斩箫,可吹牛的內(nèi)容都是我干的吏砂。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼乘客,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼狐血!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起易核,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤匈织,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后牡直,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缀匕,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年碰逸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了乡小。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡饵史,死狀恐怖满钟,靈堂內(nèi)的尸體忽然破棺而出胜榔,到底是詐尸還是另有隱情,我是刑警寧澤湃番,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布夭织,位于F島的核電站,受9級(jí)特大地震影響牵辣,放射性物質(zhì)發(fā)生泄漏摔癣。R本人自食惡果不足惜奴饮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一纬向、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧戴卜,春花似錦逾条、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至江锨,卻和暖如春吃警,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背啄育。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工酌心, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人挑豌。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓安券,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親氓英。 傳聞我的和親對(duì)象是個(gè)殘疾皇子侯勉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

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

  • 閉包(closure)是Javascript語(yǔ)言的一個(gè)難點(diǎn),也是它的特色铝阐,很多高級(jí)應(yīng)用都要依靠閉包實(shí)現(xiàn)址貌。 一、變量...
    zock閱讀 1,074評(píng)論 2 6
  • 閉包(closure)是Javascript語(yǔ)言的一個(gè)難點(diǎn)徘键,也是它的特色练对,很多高級(jí)應(yīng)用都要依靠閉包實(shí)現(xiàn)。 一啊鸭、變量...
    zouCode閱讀 1,270評(píng)論 0 13
  • ● 閉包基礎(chǔ) ● 閉包作用 ● 閉包經(jīng)典例子 ● 閉包應(yīng)用 ● 閉包缺點(diǎn) ● 參考資料 1锹淌、閉包基礎(chǔ) 作用域和作...
    lzyuan閱讀 921評(píng)論 0 0
  • 沒(méi)什么別的原因因?yàn)楦缭谝粋€(gè)新的文件夾下命名了一個(gè)相同的文件名就會(huì)報(bào)錯(cuò) "duplicate"和"symbols"。...
    小苗曉雪閱讀 165評(píng)論 0 0
  • 有時(shí)赠制, 幸福很簡(jiǎn)單赂摆; 騎一輛摩拜單車挟憔, 走一條清凈的大道, 聽一首思緒萬(wàn)千的歌曲烟号, 游走在绊谭, 既熟悉又陌生的城市,...
    金石已開閱讀 199評(píng)論 0 3