立即執(zhí)行函數(shù)的出現(xiàn)及閉包的實際使用

一秽五、立即執(zhí)行函數(shù)的出現(xiàn)

我們都知道地梨,在ES 6出現(xiàn)之前,前端開發(fā)人員在JavaScript中只能在函數(shù)中才能使用局部變量:

var a = 1 //全局變量

function createB(){
  var b = 2 //局部變量
  console.log(b)
}

createB() // 2
console.log(a) // 1
console.log(b) // b is not defined

在上面的代碼中 createB() 這個函數(shù)在聲明之后立即調(diào)用,在控制臺打印出了變量b的值掖棉。
在C語言或C++中钦睡,我們可以使用 {} 將代碼包裹起來實現(xiàn)局部變量蒂窒,但是JavaScript中有變量提升這個東西,所以在JS中這種方法并不可行赎婚。
但是這種方法還是使用到了全局變量刘绣,在哪里呢?函數(shù) createB() 挣输,雖然變量B在函數(shù)內(nèi)是一個局部變量纬凤,但是函數(shù)本身還在全局作用域中。所以我們在調(diào)用函數(shù) createB 時還是使用到了全局變量撩嚼。
怎么辦呢停士,這里我們將函數(shù) createB() 改寫成一個匿名函數(shù),并且立即調(diào)用它:

function(){
  var b = 2
  console.log(b)
}.call()

這種方法雖然解決了局部變量的問題完丽,但是在瀏覽器中執(zhí)行的時候會報錯:

function(){
  var b = 2
  console.log(b)
}.call() //Uncaught SyntaxError: Unexpected token (

于是廣大程序員試出來一些方法使得瀏覽器不報語法錯誤:

//第一種恋技,在函數(shù)前加取反符號 ! 
!function(){
  var b = 2
  console.log(b)
}.call() 

//第二種逻族,在函數(shù)前加 +/- 號
-function(){
  var b = 2
  console.log(b)
}.call() 
(function(){
  var b = 2
  console.log(b)
}).call()

//第三種蜻底,用()將函數(shù)體包裹起來
(function(){
  var b = 2
  console.log(b)
}).call()

// 還有其他方法不再一一介紹

雖然第一、第二種方法會改變函數(shù)的返回值聘鳞,但是由于我們不在乎函數(shù)的返回值薄辅,因此并不會有影響。

二抠璃、總結(jié)立即執(zhí)行函數(shù)

  1. 我們程序員不想用全局變量
  2. 我們想用局部變量
  3. ES 6之前站楚,只有函數(shù)有局部變量
  4. 于是我們聲明一個 function xxx(){},然后調(diào)用這個函數(shù)搏嗡,xxx.call()
  5. 但是函數(shù)xxx也是全局變量(全局函數(shù))窿春,因此我們不能給函數(shù)名字
  6. 就有了匿名函數(shù) function(){}.call()
  7. 但是這種寫法在 Chrome 中會報語法錯誤
  8. 程序員試出來一些方法使得瀏覽器不報錯

三拉一、閉包的出現(xiàn)

在上文中我們知道了立即執(zhí)行函數(shù)的出現(xiàn)以及作用就是實現(xiàn)局部變量,那么現(xiàn)在就出現(xiàn)了新的問題旧乞,假設(shè)我現(xiàn)在有兩個 .js 文件肯夏,這兩個文件想要相互訪問要如何實現(xiàn)份帐?

// module1.js
!function(){
  var person = {
    "name": "wky",
    "age": 18
  }
  window.person = person
}.call()

// module2.js
!function(){
  var person = wondow.person
  console.log(person)
}.call()

我們將變量person添加到window對象上锐想,這樣其他的函數(shù)內(nèi)部也可以訪問到變量person然走,但是為了避免其他函數(shù)直接操作變量person,我們修改一下這個函數(shù):

// module1.js
!function(){
  var person = {
    "name": "wky",
    "age": 18
  }
  window.personGrowUp = function(){
    person.age += 1
    return person.age
  }
}.call()

// module2.js
!function(){
  var newAge = window.personGrowUp
  console.log(newAge) // 19    
}.call()

這里module1.js函數(shù)中只暴露了一個函數(shù) personGrowUp() 决瞳,在module2.js中只能使用這個使年齡加一的函數(shù)货徙,而不能直接使用變量person,這樣就起到了一個隱藏變量的功能皮胡,在module1.js中就生成了一個閉包痴颊,因為函數(shù) personGrowUp() 使用了函數(shù)之外的一個變量person。

四屡贺、總結(jié)閉包的使用

  1. 立即執(zhí)行函數(shù)使得變量 person 無法被外部訪問
  2. 閉包使得匿名函數(shù)可以操作 person
  3. window.personGrowUp 保存了匿名函數(shù)的地址
  4. 任何地方都可以使用 window.personGrowUp 操作 person 蠢棱,但是不能直接訪問 person

五、改寫函數(shù)

我們對上面的函數(shù)進行一些簡單的改寫就可以得到一個標準的閉包:

var fn = function(){
  var person = {
    "name": "wky",
    "age": 18
  }
  return function(){
    person.age += 1
    return person.age
  }
}

var personGrowUp = fn()
personGrowUp()

這里函數(shù)fn在聲明之后立即調(diào)用甩栈,這也是一個立即執(zhí)行函數(shù)泻仙,函數(shù)fn返回一個匿名函數(shù),因此我們可以再次調(diào)用 personGrowUp 函數(shù)量没。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末玉转,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子殴蹄,更是在濱河造成了極大的恐慌究抓,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件袭灯,死亡現(xiàn)場離奇詭異刺下,居然都是意外死亡,警方通過查閱死者的電腦和手機稽荧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進店門橘茉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人姨丈,你說我怎么就攤上這事畅卓。” “怎么了构挤?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵髓介,是天一觀的道長惕鼓。 經(jīng)常有香客問我筋现,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任矾飞,我火速辦了婚禮一膨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘洒沦。我一直安慰自己豹绪,他們只是感情好,可當我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布申眼。 她就那樣靜靜地躺著瞒津,像睡著了一般。 火紅的嫁衣襯著肌膚如雪括尸。 梳的紋絲不亂的頭發(fā)上巷蚪,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天,我揣著相機與錄音濒翻,去河邊找鬼屁柏。 笑死,一個胖子當著我的面吹牛有送,可吹牛的內(nèi)容都是我干的淌喻。 我是一名探鬼主播,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼雀摘,長吁一口氣:“原來是場噩夢啊……” “哼裸删!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起阵赠,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤烁落,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后豌注,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體伤塌,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年轧铁,在試婚紗的時候發(fā)現(xiàn)自己被綠了每聪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡齿风,死狀恐怖药薯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情救斑,我是刑警寧澤童本,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站脸候,受9級特大地震影響穷娱,放射性物質(zhì)發(fā)生泄漏绑蔫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一泵额、第九天 我趴在偏房一處隱蔽的房頂上張望配深。 院中可真熱鬧,春花似錦嫁盲、人聲如沸篓叶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽缸托。三九已至,卻和暖如春瘾蛋,著一層夾襖步出監(jiān)牢的瞬間嗦董,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工瘦黑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留京革,地道東北人。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓幸斥,卻偏偏與公主長得像匹摇,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子甲葬,可洞房花燭夜當晚...
    茶點故事閱讀 45,585評論 2 359

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