溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么理解javascript閉包

發(fā)布時間:2021-11-17 15:05:58 來源:億速云 閱讀:115 作者:iii 欄目:web開發(fā)

本篇內容介紹了“怎么理解javascript閉包”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

第一梯隊理解

我個人認為閉包之所以難以理解很重要的一點在于,很多概念我們在理解的過程中都會在潛意識里和這個概念本身的名詞強度關聯(lián)在一起在揣摩這個概念的意思,如果自己的理解和這個名詞本身的字面意思看上去不那么相關的話,就會在內心產(chǎn)生巨大的懷疑感,不敢相信自己的理解是否正確,哪怕是正確的。所以在立即一個概念本身的含義過程中需要一個步驟就是將自己對概念的理解和名詞本身找到某種莫名的連接方法就好理解了。

而閉包這個名詞換做誰聽上去都不知道是在說什么,這本身就給理解這個概念造成了很大的困惑,因為一個通俗易懂的代名詞就可以很好地解釋一個概念的50%了。比如變量就是變化的字面量,條件語句,分支語句大家一聽就很好理解其概念是什么。所以首先大家需要在概念上給閉包建立一個初級的感性認識。一下這句話是我見到的簡單易懂的一種解釋。

functions that return functions

意思是:閉包就是一個函數(shù),只不過這個函數(shù)是另一個函數(shù)的返回值。

沒錯,最表面上看似乎就是這樣的。比如寫一個閉包:

function fn1() {       var temp = 10;       return function() {           console.log(++temp);       }  }  fn1()();

上面的例子里return出來的那個function就是一個非常簡單的閉包,表面上看和上面的定義語句差不多就是一個從函數(shù)里返回的函數(shù)。

***梯隊的理解到這接差不多了,雖然不正確,雖然很粗糙,但對形成一個感性認識應該是夠了,總結一個***梯隊的認識,什么是閉包:

  • 一個函數(shù)

  • 被其他函數(shù)return出來的函數(shù)。

這個時候認識里面應該有這么一個概念,就是閉包和我們已經(jīng)理解的一個概念應該差不多,那就是函數(shù),沒錯剛開始就可以這么理解,閉包就是一個函數(shù),是一個特殊的函數(shù),就好像js中的方法也是函數(shù)一樣。

第二梯隊理解

有了***梯隊的認識,我們慢慢修正大腦中對閉包的認識。有的人理解閉包就是一個嵌套在函數(shù)里的函數(shù),內部函數(shù)可以訪問外部函數(shù)的數(shù)據(jù)而已。這么理解是不對的??聪旅孢@段代碼:

function fn1() {   var temp = 10;   function fn2() {       console.log(++temp);   }   fn2() } fn1()

可是這時的fn1()無論執(zhí)行多少次打印都是11,永遠不會變,所以這還不是閉包,只有當你return出來一個內部function的時候才會形成一個閉包,閉包就是return出來的這個函數(shù)。這個內部函數(shù)可以close-over外部函數(shù)的變量直到內部的這個函數(shù)(閉包)結束掉。

這時我們再來看看***梯隊中的代碼

function fn1() {       var temp = 10;       return function() {           console.log(++temp);       }  }  vat func1 = fn1(); // func1就是一個閉包(就是fn1返回的函數(shù))。  func1(); // 打印11  func1(); // 打印12

這個時候func1是全局變量,但是打印的時候卻訪問的是fn1的局部變量temp并且,當fn1()函數(shù)執(zhí)行完之后,temp的變量并沒有被垃圾回收到仍然存在于內存中,這就是閉包的特點。也就是剛剛我們說的內部函數(shù)close-over外部函數(shù)的變量。理解這句話就可以很好的與閉包這兩個字關聯(lián)起來理解閉包這個概念了。

總結第二梯隊理解:

  1. 閉包是一個有特定功能的函數(shù)。他是一個可以讀取其他函數(shù)內部變量的一個函數(shù)。

  2. 因為在javascript中如果你想讀取一個函數(shù)內的變量(通常稱為局部變量)只有函數(shù)的子函數(shù)可以訪問。

  3. 那么將這兩個概念交叉理解,就可以簡單的理解閉包就是一個定義在函數(shù)內部的函數(shù),且可以訪問函數(shù)里的局部變量的那個函數(shù)。

  4. 在沒有閉包,我們沒法訪問函數(shù)內部的局部變量,有了閉包之后,我們就可以訪問函數(shù)內部的局部變量了,等同于閉包解決了一個問題,那就是在函數(shù)內部和函數(shù)外部之間建立了一座橋梁。

第三梯隊理解

這個時候我們可以看看官方定義的閉包:閉包是指那些能夠訪問獨立(自由)變量的函數(shù)  (變量在本地使用,但定義在一個封閉的作用域中)。換句話說,這些函數(shù)可以“記憶”它被創(chuàng)建時候的環(huán)境。

再看另一個定義:那么什么是閉包呢?這里有兩個定義。在計算機科學中(而不是數(shù)學中),一個閉包是一個函數(shù)或者一個函數(shù)的引用,以及他們所引用的環(huán)境信息(就像是一個表,這個表存儲了這個函數(shù)中引用的每一個沒有在函數(shù)內聲明的變量)。

這兩個定義中都有一個概念,***個里“封閉的作用域”,第二個里“所引用的環(huán)境信息”。這里我們都可以用上面的close-over外部函數(shù)的變量暫時理解。

也就是閉包總是要有兩個部分的:

  1. 一部分是一個函數(shù)。

  2. 另一個部分是被這個函數(shù)“包住”的(有的理解為“帶走”的,或者是close-over住的)一些環(huán)境信息(可以理解環(huán)境信息就是變量),但是卻不在這個函數(shù)中聲明的變量表(稱之為free  variables或者outer variables)。

還有一個不是那么呆的定義:閉包允許你封裝一些行為(函數(shù)就是行為),像其他對象一樣將它傳來傳去(函數(shù)是first-class  function),但是不論怎樣,它仍然保持著對原來最初上下文的訪問能力(它還能訪問到 outer variables)。

這個時候的理解就比較抽象了,因為又涉及到作用域的概念,又是一個封閉的作用域。其實上面括號中有一段話(就像是一個表,這個表存儲了這個函數(shù)中引用的每一個沒有在函數(shù)內聲明的變量),這個表就是在定義這個閉包的“閉”的范圍有哪些。

第四梯隊理解

閉包通過訪問外部變量,一個閉包可以維持(keep  alive)這些變量。在內部函數(shù)和外部函數(shù)的例子中,外部函數(shù)可以創(chuàng)建局部變量,并且最終退出;但是,如果任何一個或多個內部函數(shù)在它退出后卻沒有退出,那么內部函數(shù)就維持了外部函數(shù)的局部數(shù)據(jù)。

“怎么理解javascript閉包”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網(wǎng)站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI