閉包

一高蜂、閉包定義:

  • 閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)沥匈≌嵛梗—— 阮一峰

  • 只要有一個(gè)函數(shù)使用了它外面的變量,這個(gè)函數(shù)就是一個(gè)閉包高帖。

  • 閉包就是作用域的特殊使用方式缰儿。

二、全局變量和局部變量散址。

1乖阵、全局變量

方式1

var a = 5;

注意:該句不能包含在function內(nèi)预麸,否則是局部變量瞪浸。

var n = 111;  
function f1() {
  console.log(n);  
}  
f1(); // 111

方式2

a = 5;

注意:即使該語(yǔ)句是在一個(gè)function內(nèi)师崎,當(dāng)該function被執(zhí)行后a變成了全局變量默终。

function f1() {
   n = 999; 
}  
f1(); 
console.log(n)// 999

方式3

window.a;
window.a = 5;

注意:這種方式經(jīng)常被用到一個(gè)匿名函數(shù)執(zhí)行后將一些函數(shù)公開(kāi)到全局

window.jQuery = window.$ = jQuery;

2椅棺、局部變量

方式1

function f1(){
  var n=999;
}
console.log(n) //error

在函數(shù)外部自然無(wú)法讀取函數(shù)內(nèi)的局部變量犁罩。


方式2

{
  let q = 1 //局部變量
}
console.log(q)//error

三、外部讀取局部變量

正常情況下两疚,外部是無(wú)法讀取局部變量的床估;只有通過(guò)變通方法才能實(shí)現(xiàn)。

方法1

再定義一個(gè)函數(shù)

function f1() {
  var n = 111; 
  function f2() {
    console.log(n); //111
  }
}  

既然f2可以讀取f1中的局部變量诱渤,那么只要把f2作為返回值丐巫,就可以在f1的外部讀取它內(nèi)部的局部變量了。

function f1() {
  var n = 111; 
  function f2() {
    console.log(n); //111  
  }
  return f2
}  
var a = f1();
a()//111

方法2
運(yùn)用window做通訊勺美。

//在一個(gè)立即執(zhí)行函數(shù)訪問(wèn)另一個(gè)立即執(zhí)行函數(shù)中的值
! function () {
  var a = 1 //局部變量
  window.username = a //a賦值給window,window是全局變量

}()
! function () {
  console.log(window.username) //通過(guò)window取得a的值
}()

在海洋中兩座孤島之間递胧,靠船來(lái)通訊(window)。

如圖:


說(shuō)明.png

方法3
在一個(gè)立即執(zhí)行函數(shù)訪問(wèn)另一個(gè)立即執(zhí)行函數(shù)中的值赡茸,只能讀缎脾。

    ! function () {
      var user = {
        name: 'lili',
        age: 20
      }
      window.users = {
        names: function () {
          return user.name
        },
        ages: function () {
          return user.age
        }
      }
      //不能讓別的作用域改user,只能讀占卧。

    }()

    ! function () {
      window.users.names() // lili
      window.users.ages() // 20

    }()


四遗菠、閉包用途

一般情況下使用閉包是為了:
1联喘、可以讀取函數(shù)內(nèi)部的變量,如:方法1 方法2
2辙纬、暫存數(shù)據(jù)

  function f1(){

    var n=999;

    nAdd=function(){n+=1}

    function f2(){
      console.log(n);
    }

    return f2;

  }

  var result=f1();

  result(); // 999

  nAdd();

  result(); // 1000

在這段代碼中豁遭,result實(shí)際上就是閉包f2函數(shù)。它一共運(yùn)行了兩次贺拣,第一次的值是999蓖谢,第二次的值是1000。這證明了譬涡,函數(shù)f1中的局部變量n一直保存在內(nèi)存中蜈抓,并沒(méi)有在f1調(diào)用后被自動(dòng)清除。

這段代碼中另一個(gè)值得注意的地方昂儒,就是“nAdd=function(){n+=1}”這一行沟使,首先在nAdd前面沒(méi)有使用var關(guān)鍵字,因此nAdd是一個(gè)全局變量渊跋,而不是局部變量腊嗡。其次,nAdd的值是一個(gè)匿名函數(shù)(anonymous function)拾酝,而這個(gè)匿名函數(shù)本身也是一個(gè)閉包燕少,所以nAdd相當(dāng)于是一個(gè)setter,可以在函數(shù)外部對(duì)函數(shù)內(nèi)部的局部變量進(jìn)行操作


五蒿囤、總結(jié)

1客们、有一個(gè)地方需要注意,函數(shù)內(nèi)部聲明變量的時(shí)候材诽,一定要使用var命令底挫。如果不用的話,你實(shí)際上聲明了一個(gè)全局變量脸侥,如:方式2

2建邓、閉包會(huì)在父函數(shù)外部,改變父函數(shù)內(nèi)部變量的值睁枕。如:方法3

3官边、由于閉包會(huì)使得函數(shù)中的變量都被保存在內(nèi)存中,內(nèi)存消耗很大外遇,所以不能濫用閉包注簿。


參考:

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

MDN


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市跳仿,隨后出現(xiàn)的幾起案子诡渴,更是在濱河造成了極大的恐慌,老刑警劉巖塔嬉,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件玩徊,死亡現(xiàn)場(chǎng)離奇詭異租悄,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)恩袱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門泣棋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人畔塔,你說(shuō)我怎么就攤上這事潭辈。” “怎么了澈吨?”我有些...
    開(kāi)封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵把敢,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我谅辣,道長(zhǎng)修赞,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任桑阶,我火速辦了婚禮柏副,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蚣录。我一直安慰自己割择,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布萎河。 她就那樣靜靜地躺著荔泳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪虐杯。 梳的紋絲不亂的頭發(fā)上玛歌,一...
    開(kāi)封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音厦幅,去河邊找鬼沾鳄。 笑死,一個(gè)胖子當(dāng)著我的面吹牛确憨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瓤的,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼休弃,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了圈膏?” 一聲冷哼從身側(cè)響起塔猾,我...
    開(kāi)封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎稽坤,沒(méi)想到半個(gè)月后丈甸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體糯俗,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年睦擂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了得湘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡顿仇,死狀恐怖淘正,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情臼闻,我是刑警寧澤鸿吆,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站述呐,受9級(jí)特大地震影響惩淳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜乓搬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一黎泣、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧缤谎,春花似錦抒倚、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至频敛,卻和暖如春项郊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背斟赚。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工着降, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人拗军。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓任洞,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親发侵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子交掏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

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

  • 閉包(closure)是Javascript語(yǔ)言的一個(gè)難點(diǎn),也是它的特色刃鳄,很多高級(jí)應(yīng)用都要依靠閉包實(shí)現(xiàn)盅弛。 一、變量...
    zock閱讀 1,075評(píng)論 2 6
  • ● 閉包基礎(chǔ) ● 閉包作用 ● 閉包經(jīng)典例子 ● 閉包應(yīng)用 ● 閉包缺點(diǎn) ● 參考資料 1、閉包基礎(chǔ) 作用域和作...
    lzyuan閱讀 937評(píng)論 0 0
  • 閉包(closure)是Javascript語(yǔ)言的一個(gè)難點(diǎn)挪鹏,也是它的特色见秽,很多高級(jí)應(yīng)用都要依靠閉包實(shí)現(xiàn)。 一讨盒、變量...
    zouCode閱讀 1,271評(píng)論 0 13
  • 作用域和閉包是 JavaScript 最重要的概念之一解取,想要進(jìn)一步學(xué)習(xí) JavaScript,就必須理解 Java...
    劼哥stone閱讀 1,177評(píng)論 1 13
  • 卡爾維諾中文站留言板這個(gè)帖子專門用作卡爾維諾中文站的留言板催植,歡迎大家留言和提問(wèn)肮蛹。...阮一峰2007-01-04T...
    舟漁行舟閱讀 322評(píng)論 0 1