徹底明白閉包!

閉包這個話題是每個前端開發(fā)者都無法避開的,也成為了面試中的常見問題,或許你能說出自己背下來的答案,但是很少有同學(xué)會能真正搞懂其中的原理。知其然,更要知其所以然,今天我就來帶領(lǐng)大家通過剖析閉包的代碼,讓大家徹底明白閉包這個概念


看下面一段經(jīng)典的閉包應(yīng)用代碼


那么 JavaScript 解析器是如何執(zhí)行這段代碼的呢?今天我們再一步一步解釋一下上面代碼的執(zhí)行過程。


1、行 1-8 在全局執(zhí)行上下文中定義了一個新的變量 count,被賦了一個函數(shù)定義。


2、行 9 在全局執(zhí)行上下文中定義了變量 increment。


3、行 9 執(zhí)行 count 函數(shù),并且將其返回值賦給變量 increment。


4、然后再次來到行 1-8,創(chuàng)建了一個本地執(zhí)行上下文。


5、行 2 在本地執(zhí)行上下文中定義了一個變量 now 賦值為 0。


6、行 3-6 到了核心步驟,在本地執(zhí)行上下文中定義一個變量 myFunc,變量內(nèi)容是一個新的函數(shù)定義,同時我們也會創(chuàng)建一個閉包,并且讓其成為函數(shù)定義的一部分,這個閉包包含了該函數(shù)所處的作用域內(nèi)的變量,也就是 now。我們可以這樣用下面這段偽代碼幫助理解



所以,只要 myFunc 這個函數(shù)(或者被賦給其它變量)存在,它的閉包就會一直跟著存在。

7、行 7 返回了 myFunc 變量的內(nèi)容,本地執(zhí)行上下文被銷毀,myFunc 和 now變量不復(fù)存在,但返回了 myFunc 的函數(shù)定義和它的閉包。


8、行 9 在全局執(zhí)行上下文中定義了 increment 變量,其值為 count 函數(shù)的執(zhí)行結(jié)果,于是 increment 變量現(xiàn)在包含了一個函數(shù)定義和閉包,它不再是 myFunc,但是在全局執(zhí)行上下文中,它有了一個新的身份 increment。


9、行 10 定義了一個新的變量 r1 暫時賦值為 undefined。


10、行 10 發(fā)現(xiàn)有 () 表示這是一個需要執(zhí)行的函數(shù),于是查找變量 increment,找到后執(zhí)行該函數(shù),它包含了 4-5 行返回的函數(shù)定義。


11、開始執(zhí)行 increment 函數(shù),創(chuàng)建一個本地執(zhí)行上下文。


12、行 4 我們需要去找一個變量 now,當(dāng)前函數(shù)中并不存在這個變量,然后在去全局執(zhí)行上下文中查找之前,我們會先檢查一下閉包,最后發(fā)現(xiàn)閉包中確實包含一個變量 now 值為 0。執(zhí)行完 now += 1 后,它的值變成了 1,然后又將這個值存回了閉包中的 now 變量中,于是現(xiàn)在閉包中 now 的值就變成 1 了。


13、行 5 我們返回了 now 的值 1 然后銷毀了本地執(zhí)行上下文。


14、回到行 10,返回值 1 被賦給了 r1 變量。


15、行 11-12 又重復(fù)了上面的執(zhí)行過程,閉包中的 now 也再次經(jīng)歷了被取出,被 +1,又被存回到閉包中的過程,最終變成了 3。


16、行 13,打印出 r1 r2 和 r3 的值,分別是 1 2 3。


每當(dāng)一個函數(shù)被聲明的時候,它就會包含一個函數(shù)定義和閉包,這個閉包包含該函數(shù)所處的上下文(也就是父級作用域)所有變量的集合。本質(zhì)上來說,閉包就是一個作用域的留存。


有同學(xué)要問了,是不是所有函數(shù)都有閉包呢,即使在全局下創(chuàng)建的函數(shù)?答案:是。但由于在全局下創(chuàng)建的函數(shù)本身就能訪問全局下的變量,所以閉包這個概念在這里就并沒有多大意義。然而對于這種函數(shù)返回函數(shù)的場景,由于被返回函數(shù)的父級也是一個函數(shù),所以更能突出閉包的作用,我們常說的閉包指的也就是這種場景。


其實我們也可以在 Chrome F12 中查看這個閉包,在 Console 中輸入下面的代碼回車


結(jié)果如下圖


可以看到,increment 有 3 個 Scope,其中就包含了 Closure 閉包,也可以明確看到里面的 now 變量。


感興趣的小伙伴,可以關(guān)注公眾號【grain先森】,回復(fù)關(guān)鍵詞 “vue”,獲取更多資料,更多關(guān)鍵詞玩法期待你的探索~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學(xué)習(xí)記錄文檔,今天18年5月份再次想寫文章,發(fā)現(xiàn)簡書還為我保存起的...
    Jenaral閱讀 3,123評論 2 9
  • 86.復(fù)合 Cases 共享相同代碼塊的多個switch 分支 分支可以合并, 寫在分支后用逗號分開。如果任何模式...
    無灃閱讀 1,551評論 1 5
  • 我比較喜歡的一部日本電影就是三池崇史導(dǎo)演的《十三刺客》。 場面及其的慘烈,血腥。演員陣容強大,主演有役所廣司、山田...
    侃扯聯(lián)盟閱讀 387評論 0 1
  • 馬利小天使,小歌文,申內(nèi)八色。筆的話套裝送的自來水筆一點也不好用但是我現(xiàn)在隨便涂確實沒啥問題,也有用過狼毫和九紫一...
    ksalucard閱讀 359評論 0 0
  • 是有多久沒有靜下心來,讀完一本書了。 這本郭德綱寫的,過的剛好,讀起來很爽。 有一些咬文嚼字,有一些古書典籍,有一...
    十八k閱讀 220評論 0 0

友情鏈接更多精彩內(nèi)容