JavaScript: 零基礎(chǔ)輕松學(xué)閉包(1)

注:本人發(fā)布的所有文章均為原創(chuàng)吩谦,未經(jīng)作者許可,切勿轉(zhuǎn)載膝藕,謝謝式廷。

本文面向初學(xué)者,大神輕噴芭挽。

  • 閉包是什么滑废?

初學(xué)javascript的人,都會(huì)接觸到一個(gè)東西叫做閉包袜爪,聽起來感覺很高大上的蠕趁。網(wǎng)上也有各種五花八門的解釋,其實(shí)我個(gè)人感覺辛馆,沒必要用太理論化的觀念來看待閉包俺陋。

事實(shí)上,你每天都在用閉包怀各,只是你不知道罷了倔韭。

比如:

var cheese = '奶酪';

var test = function(){
    alert(cheese);
}

OK,你已經(jīng)寫了一個(gè)閉包瓢对。

  • 函數(shù)也是一個(gè)數(shù)據(jù)類型

變量 cheese 是在全局作用域中的一個(gè)變量寿酌,當(dāng)你創(chuàng)建了一個(gè) test 函數(shù),那么硕蛹,test 和 cheese 就共享一個(gè)全局作用域醇疼。

你要額外明白的一點(diǎn)是,在js中法焰,函數(shù)和變量本質(zhì)上是一個(gè)東西秧荆。函數(shù)也是一個(gè)數(shù)據(jù)類型。

從上面的定義中也能看出來這一點(diǎn)埃仪。你要是不相信的話乙濒,我們來看一下咯。

alert(cheese);
alert(test);
Paste_Image.png
Paste_Image.png

讓我們?cè)賮砜纯?test 和 cheese各是什么類型:

alert(typeof test);
Paste_Image.png
alert(typeof cheese);
Paste_Image.png

看到了吧卵蛉,只是類型不同而已颁股,他們都是數(shù)據(jù)類型。

唯一的不同點(diǎn)就是傻丝,函數(shù)類型的 test 可以擁有自己內(nèi)部邏輯甘有,而string類型的 cheese 只能存放一個(gè)字面值,這就是區(qū)別葡缰,僅此而已亏掀。

一目了然了忱反,唯一不同的就是普通變量是字面值一樣的存在,而函數(shù)需要打個(gè)括號(hào)才能執(zhí)行而已滤愕。

你看温算,我現(xiàn)在打一個(gè)括號(hào):

test();
Paste_Image.png

打了括號(hào),才會(huì)執(zhí)行函數(shù)里面的邏輯该互。

  • 作用域

讓我們回到閉包米者,現(xiàn)在將之前的代碼做一個(gè)小小的變動(dòng):

var cheese = '奶酪';
var test = function(){
    alert(cheese);
}

function test2(){
    var cheese = null;
    test();
}

test2();

那么韭畸,你覺得現(xiàn)在 alert 出來的是 null 還是奶酪呢宇智?

思考一下。胰丁。随橘。

對(duì)的,彈出來的還是奶酪锦庸。

Paste_Image.png

之前已經(jīng)說過了机蔗,函數(shù) test 和 變量 cheese 同處于一片藍(lán)天下 -- 同一個(gè)作用域。

函數(shù) test 和 變量 cheese 共同享有的作用域叫做全局作用域甘萧,就好像地球一樣萝嘁,我們所有的人都享有這個(gè)地球,能夠在這里呼吸扬卷,吃飯牙言,玩耍。

對(duì)test而言怪得,他能訪問到的作用域只有它本身的閉包和全局作用域:

Paste_Image.png

也就是說咱枉,正常情況下他訪問不到其他閉包里的內(nèi)容,在 test2 里面定義的變量跟它沒有半毛錢關(guān)系徒恋,所以彈出來的 cheese 依舊是全局作用域里的 cheese蚕断。

函數(shù)可以創(chuàng)造自己的作用域。

我們剛才定義了一個(gè) test 函數(shù)入挣,{ } 包裹起來的部分就形成了一個(gè)新的作用域亿乳,也就是所謂的閉包。

其實(shí)你深刻了解了作用域的原理后径筏,閉包也就理解了葛假。

就好比地球是一個(gè)全局作用域,你自己家的房子是一個(gè)函數(shù)匠璧,你的房子是私人空間桐款,就是一個(gè)局部作用域,也就是你自己建了一個(gè)閉包夷恍!

你透過窗戶可以看見外邊的景色魔眨,比如院子里的一棵芭蕉樹媳维,你于是通過眼鏡觀察看到了芭蕉樹的顏色,高度遏暴,枝干的粗細(xì)等等侄刽。

這一棵芭蕉樹相當(dāng)于一個(gè)全局變量,你在自己的閉包內(nèi)可以訪問到它的數(shù)據(jù)朋凉。

所以州丹,在這個(gè)例子中,test 就是一個(gè)房子杂彭,在里面可以通過窗戶訪問到全局作用域中的奶酪 —— 變量 cheese墓毒。

也就是說,cheese 在被 test 訪問到的時(shí)候亲怠,就進(jìn)入了它的閉包所计。

這樣解釋,你是否覺得好理解一點(diǎn)呢团秽?

現(xiàn)在你是否可以理解一開始我說主胧,閉包這東西其實(shí)我們天天都在用的意思了呢?

我們給出閉包的第一個(gè)注解:

1. 閉包就是在函數(shù)被創(chuàng)建的時(shí)候习勤,存在的一個(gè)私有作用域踪栋,并且能夠訪問所有的父級(jí)作用域。

回到剛才的例子:

var cheese = '奶酪';
var test = function(){
    alert(cheese);
}

function test2(){
    var cheese = null;
    test();
}

在這個(gè)例子中图毕,test 和 test2 各自享有一個(gè)作用域夷都,對(duì)不對(duì)?而且他們互相不能訪問吴旋。比如损肛,我在 test 中定義的一個(gè)變量,test2就無法直接訪問荣瑟。

var test = function(){
    var i = 10;
}

function test2(){
    alert(i);
}

test2();

像這樣治拿,一旦執(zhí)行 test2 函數(shù),編譯就不通過笆焰,因?yàn)樵?test2的閉包內(nèi)劫谅,根本找不到變量 i 。它首先會(huì)在自己的閉包內(nèi)尋找 i嚷掠,找不到的話就去父級(jí)作用域里找捏检,這邊的父級(jí)就是全局作用域,很遺憾不皆,還是沒有贯城。這就是所謂的作用域鏈,它會(huì)一級(jí)一級(jí)往上找霹娄。如果找到最頂層能犯,還是找不到的話鲫骗,就會(huì)報(bào)錯(cuò)了。

Paste_Image.png

在這里踩晶,還有一個(gè)需要注意的點(diǎn)就是:如果某一個(gè)閉包中對(duì)全局作用域(或父級(jí)作用域)中的變量進(jìn)行了修改执泰,那么任何引用該變量的閉包都會(huì)受到牽連。

這的確是一個(gè)需要注意的地方渡蜻。

舉個(gè)例子

var cheese = '奶酪';

var test = function(){
    cheese = '奶酪被偷吃了术吝!'
}

function test2(){
    alert(cheese);
}
test();
test2();

結(jié)果是:

Paste_Image.png

很有趣,是不是呢茸苇?

當(dāng)我們?cè)诙x一個(gè)函數(shù)排苍,就產(chǎn)生了一個(gè)閉包,如果這個(gè)函數(shù)里面又有若干的內(nèi)部函數(shù)税弃,就是閉包嵌套著閉包纪岁。

像這樣:

function house(){
    
    var footBall = '足球';
    /* 客廳 */
    function livingRoom(){
        var table = '餐桌';
        var sofa = '沙發(fā)';
        alert(footBall);
    }
    
    /* 臥室 */
    function bedRoom(){
        var bed = '大床';
    }
    
    livingRoom();
}

house(); 

函數(shù)house是一個(gè)閉包,里面又定義了兩個(gè)函數(shù)则果,分別是livingRoom客廳,和bedRoom臥室漩氨,它們各自形成一個(gè)自己的閉包西壮。對(duì)它們而言,父級(jí)作用域就是house叫惊。

如果我們希望在客廳里踢足球款青,在livingRoom函數(shù)執(zhí)行的時(shí)候,它會(huì)先在自己的閉包中找足球霍狰,如果沒找到抡草,就去house里面找。一層一層往上找蔗坯,直至找到了為止谣辞。當(dāng)然澎现,這個(gè)例子可能不是很恰當(dāng)。但起碼展示了作用域,閉包之間的聯(lián)系擂啥。

再說明一下, 閉包就是在函數(shù)被創(chuàng)建的時(shí)候嘀掸,存在的一個(gè)私有作用域涯竟,并且能夠訪問所有的父級(jí)作用域。因此卸奉,從理論上講钝诚,任何函數(shù)都是一個(gè)閉包!

本章結(jié)束 ...

剽悍一小兔榄棵,電氣自動(dòng)化畢業(yè)凝颇。
參加工作后對(duì)計(jì)算機(jī)感興趣郎嫁,深知初學(xué)編程之艱辛。
希望將自己所學(xué)記錄下來祈噪,給初學(xué)者一點(diǎn)幫助泽铛。

免責(zé)聲明: 博客中所有的圖片素材均來自百度搜索,僅供學(xué)習(xí)交流辑鲤,如有問題請(qǐng)聯(lián)系我盔腔,侵立刪,謝謝月褥。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末弛随,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子宁赤,更是在濱河造成了極大的恐慌舀透,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件决左,死亡現(xiàn)場(chǎng)離奇詭異愕够,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)佛猛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門惑芭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人继找,你說我怎么就攤上這事遂跟。” “怎么了婴渡?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵幻锁,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我边臼,道長(zhǎng)哄尔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任硼瓣,我火速辦了婚禮究飞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘堂鲤。我一直安慰自己亿傅,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布瘟栖。 她就那樣靜靜地躺著葵擎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪半哟。 梳的紋絲不亂的頭發(fā)上酬滤,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天签餐,我揣著相機(jī)與錄音,去河邊找鬼盯串。 笑死氯檐,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的体捏。 我是一名探鬼主播冠摄,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼几缭!你這毒婦竟也來了河泳?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤年栓,失蹤者是張志新(化名)和其女友劉穎拆挥,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體某抓,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡纸兔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了搪缨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片食拜。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖副编,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情流强,我是刑警寧澤痹届,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站打月,受9級(jí)特大地震影響队腐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜奏篙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一柴淘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧秘通,春花似錦为严、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至话原,卻和暖如春夕吻,著一層夾襖步出監(jiān)牢的瞬間诲锹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工涉馅, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留归园,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓稚矿,卻偏偏與公主長(zhǎng)得像庸诱,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子盐捷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

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