JavaScript閉包

什么是JS閉包巾表?

分分鐘了解弄懂JavaScript閉包

先看一段代碼:

function a(){ 
  var n = 0; 
  function couter() { 
    n++; 
    console.log(n); 
  } 
  couter(); 
  couter(); 
} 
a(); //控制臺(tái)輸出1汁掠,再輸出2

再來(lái)看一段代碼:

function a(){ 
  var n = 0; 
  this.couter = function () { 
    n++; 
    console.log(n); 
  }; 
} 
var c = new a(); 
c.couter(); //控制臺(tái)輸出1 
c.couter(); //控制臺(tái)輸出2

什么是閉包?這就是閉包集币!簡(jiǎn)單吧调塌。

有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域內(nèi)變量的函數(shù)都是閉包。這里 couter 函數(shù)訪問(wèn)了構(gòu)造函數(shù) a 里面的變量 n惠猿,所以形成了一個(gè)閉包羔砾。 再來(lái)看一段代碼:

function a(){ 
  var n = 0; 
  function couter(){ 
    n++; 
    console.log(n); 
  } 
  return couter; 
} 
var c = a(); 
c(); //控制臺(tái)輸出1 
c(); //控制臺(tái)輸出2

看看是怎么執(zhí)行的: var c = a(),這一句 a()返回的是函數(shù) couter偶妖,那這句等同于 var c = couter; c()姜凄,這一句等同于 couter(); 注意,函數(shù)名只是一個(gè)標(biāo)識(shí)(指向函數(shù)的指針)趾访,而()才是執(zhí)行函數(shù)态秧。 后面三句翻譯過(guò)來(lái)就是: var c = couter; couter(); couter();,跟第一段代碼有區(qū)別嗎扼鞋? 沒(méi)有申鱼。

為什么要這樣寫?

我們知道云头,js的每個(gè)函數(shù)都是一個(gè)個(gè)小黑屋捐友,它可以獲取外界信息,但是外界卻無(wú)法直接看到里面的內(nèi)容溃槐。將變量 n 放進(jìn)小黑屋里匣砖,除了 couter 函數(shù)之外,沒(méi)有其他辦法能接觸到變量 n昏滴,而且在函數(shù) a 外定義同名的變量 n 也是互不影響的猴鲫,這就是所謂的增強(qiáng)“封裝性”。 而之所以要用 return 返回函數(shù)標(biāo)識(shí) couter谣殊,是因?yàn)樵?a 函數(shù)外部無(wú)法直接調(diào)用 couter 函數(shù)拂共,所以 return couter 與外部聯(lián)系起來(lái),在代碼 2 中的 this 也是將 couter 與外部聯(lián)系起來(lái)而已姻几。

常見(jiàn)的陷阱

function createFunctions(){ 
  var result = new Array(); 
  for (var i=0; i < 10; i++){ 
    result[i] = function(){ 
      return i; 
    }; 
  } 
  return result; 
} 
var funcs = createFunctions(); 
for (var i=0; i < funcs.length; i++){ 
  console.log(funcs[i]()); 
}

乍一看宜狐,以為輸出 0~9 ,萬(wàn)萬(wàn)沒(méi)想到輸出10個(gè)10鲜棠?

這里的陷阱就是:函數(shù)帶()才是執(zhí)行函數(shù)肌厨! 單純的一句 var f = fnction() { alert('Hi'); }; 是不會(huì)彈窗的,后面接一句 f(); 才會(huì)執(zhí)行函數(shù)內(nèi)部的代碼豁陆。上面代碼翻譯一下就是:

var result = new Array(), i; 
result[0] = function(){ return i; }; //沒(méi)執(zhí)行函數(shù)柑爸,函數(shù)內(nèi)部不變,不能將函數(shù)內(nèi)的i替換盒音! 
result[1] = function(){ return i; }; //沒(méi)執(zhí)行函數(shù)表鳍,函數(shù)內(nèi)部不變馅而,不能將函數(shù)內(nèi)的i替換! 
... 
result[9] = function(){ return i; }; //沒(méi)執(zhí)行函數(shù)譬圣,函數(shù)內(nèi)部不變瓮恭,不能將函數(shù)內(nèi)的i替換! 
i = 10; 
funcs = result; 
result = null; 

console.log(i); // funcs[0]()就是執(zhí)行 return i 語(yǔ)句厘熟,就是返回10 
console.log(i); // funcs[1]()就是執(zhí)行 return i 語(yǔ)句屯蹦,就是返回10 
... 
console.log(i); // funcs[9]()就是執(zhí)行 return i 語(yǔ)句,就是返回10

為什么只垃圾回收了 result绳姨,但卻不收了 i 呢登澜? 因?yàn)?i 還在被 function 引用著啊。好比一個(gè)餐廳飘庄,盤子總是有限的脑蠕,所以服務(wù)員會(huì)去巡臺(tái)回收空盤子,但還裝著菜的盤子他怎么敢收跪削? 當(dāng)然谴仙,你自己手動(dòng)倒掉了盤子里面的菜(=null),那盤子就會(huì)被收走了碾盐,這就是所謂的內(nèi)存回收機(jī)制晃跺。 至于 i 的值怎么還能保留,其實(shí)從文章開頭一路讀下來(lái)廓旬,這應(yīng)該沒(méi)有什么可以糾結(jié)的地方哼审。盤子里面的菜,吃了一塊不就應(yīng)該少一塊嗎孕豹?

總結(jié)一下

閉包就是一個(gè)函數(shù)引用另外一個(gè)函數(shù)的變量,因?yàn)樽兞勘灰弥圆粫?huì)被回收十气,因此可以用來(lái)封裝一個(gè)私有變量励背。這是優(yōu)點(diǎn)也是缺點(diǎn),不必要的閉包只會(huì)徒增內(nèi)存消耗砸西!另外使用閉包也要注意變量的值是否符合你的要求叶眉,因?yàn)樗拖褚粋€(gè)靜態(tài)私有變量一樣。閉包通常會(huì)跟很多東西混搭起來(lái)芹枷,接觸多了才能加深理解衅疙,這里只是開個(gè)頭說(shuō)說(shuō)基礎(chǔ)性的東西。

看完文章鸳慈,還有福利拿哦饱溢,往下看??????
感興趣的小伙伴可以在公號(hào)【grain先森】后臺(tái)回復(fù)【190315】獲取【Css 參考規(guī)范】,可以轉(zhuǎn)發(fā)朋友圈和你的朋友分享哦走芋。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末绩郎,一起剝皮案震驚了整個(gè)濱河市潘鲫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌肋杖,老刑警劉巖溉仑,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異状植,居然都是意外死亡浊竟,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門津畸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)振定,“玉大人,你說(shuō)我怎么就攤上這事洼畅》园福” “怎么了?”我有些...
    開封第一講書人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵帝簇,是天一觀的道長(zhǎng)徘郭。 經(jīng)常有香客問(wèn)我,道長(zhǎng)丧肴,這世上最難降的妖魔是什么残揉? 我笑而不...
    開封第一講書人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮芋浮,結(jié)果婚禮上抱环,老公的妹妹穿的比我還像新娘。我一直安慰自己纸巷,他們只是感情好镇草,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著瘤旨,像睡著了一般梯啤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上存哲,一...
    開封第一講書人閱讀 51,698評(píng)論 1 305
  • 那天因宇,我揣著相機(jī)與錄音,去河邊找鬼祟偷。 笑死察滑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的修肠。 我是一名探鬼主播贺辰,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了魂爪?” 一聲冷哼從身側(cè)響起先舷,我...
    開封第一講書人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎滓侍,沒(méi)想到半個(gè)月后蒋川,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡撩笆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年捺球,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片夕冲。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡氮兵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出歹鱼,到底是詐尸還是另有隱情泣栈,我是刑警寧澤,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布弥姻,位于F島的核電站南片,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏庭敦。R本人自食惡果不足惜疼进,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望秧廉。 院中可真熱鬧伞广,春花似錦、人聲如沸疼电。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蔽豺。三九已至灾票,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間茫虽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工既们, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留濒析,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓啥纸,卻偏偏與公主長(zhǎng)得像号杏,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

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

  • 閉包(closure)是Javascript語(yǔ)言的一個(gè)難點(diǎn)盾致,也是它的特色主经,很多高級(jí)應(yīng)用都要依靠閉包實(shí)現(xiàn)。 一庭惜、變量...
    風(fēng)蕭蕭易水寒_1196閱讀 258評(píng)論 0 0
  • 閉包(closure)是Javascript語(yǔ)言的一個(gè)難點(diǎn)罩驻,也是它的特色,很多高級(jí)應(yīng)用都要依靠閉包實(shí)現(xiàn)护赊。 一惠遏、變量...
    zouCode閱讀 1,271評(píng)論 0 13
  • 如果要了解閉包,我們需要先了解閉包的由來(lái)骏啰,閉包的產(chǎn)生节吮,源于JS的詞法作用域 詞法作用域 作用域是指一個(gè) 變量能夠訪...
    羊烊羴閱讀 239評(píng)論 0 2
  • 那么,就這樣吧判耕。俗到底吧透绩,煙阿 酒阿 。 我于2018年9月19號(hào)愛(ài)上一個(gè)人壁熄。 于2018年9月20號(hào)決定不愛(ài)她帚豪。...
    行者阿常閱讀 137評(píng)論 0 0
  • 說(shuō)起決斷志鞍,其實(shí)我特別喜歡,盡管我也有很多時(shí)候不知道如何決斷方仿,但我有自己一套決斷的方法固棚,不一定對(duì),但是對(duì)我有效:例如...
    Yolanda_Hu閱讀 190評(píng)論 0 0