什麼是閉包?

時間 2021-05-11 20:03:20

1樓:吻住我的香腸嘴

當乙個函式執行的時候,需要訪問當前函式所在活動物件的上層活動物件(且上層活動物件不是全域性物件)的值物件的值的時候,這個時候就會產生乙個閉包。

如果訪問的值乙個在上層活動物件的值物件中,還有乙個在上上層活動物件的值物件中的話,就會產生兩個閉包。

簡而言之,閉包只有在函式呼叫時,且需要訪問「上層區域性函式作用域的值」的時候才會產生。

所謂值物件,就是這個函式在執行的時候建立的,用於儲存當前活動物件執行時用到的所有資料的集合,這個集合的構成包含簡單資料型別和引用資料型別(就是值與內部函式),如果訪問到window物件上的值,是通過作用域鏈的末端去訪問得到的,不再這個所謂的值物件中,雖然表象都能訪問到,但是概念是不同的。

值物件在領域驅動設計相關的書籍中有介紹。

所謂活動物件,就是當前函式執行時所在的執行棧環境,函式的巢狀表達了活動物件的鏈結關係,就是所謂的作用域鏈。

乙個活動物件等價於乙個上下文環境,多個活動物件(上下文環境)的先後鏈結關係組成了作用域鏈。

這個不就是資料結構中的鍊錶的概念嗎,可以去看看資料結構的書籍。

這句話理解的關鍵就是活動物件和值物件的理解,注意點是上層活動物件不是全域性物件。

所謂紮實的計算機基礎,就是在於理解某些具象的應用,找到書中知識對應某些技術細節的具象表達,就會幫助你理解這個技術的內涵,並且生動的解釋書本中那些看不懂的概念到底在表達什麼,所以看書的目的在於建立知識索引,然後從技術細節中找到對應的知識索引,理論與實踐相結合,從而才能掌握知識,做到正真的計算機基礎夠紮實。

可以看看編譯原理的書籍。

2樓:夢涯

可以了解一下 lexical scope。

3樓:

一句話解釋就是:存在自由變數的函式就是閉包。

自由變數和約束變數的直觀感覺是:

比如 const f = (x) => a * x + b,你把 x 換成 y,const f = (y) => a * y + b,這兩個函式的語義是一樣的,但是你把 a 變成 c,const f = (x) => c * x+ b,這個函式的語義就變了。 x 是約束變數,a 和 b 是自由變數。

const f = (x) => 中,包含了變數 , 除了 x 外,其中的 y 也可以變成 z 而不改變語義,所以 y 和 x 一樣,也是約束變數。

「約束變數」裡的「約束」,在 js 裡是指是否受到當下的函式作用域約束。

4樓:jSORoROWy

說閉包可能很難理解,但是說函式變數,你可能一下子就懂了閉包就是函式變數,把函式賦值(注意是值不是指標)給變數就是閉包了所謂的閉包,其實就是儲存了函式及其所有的關聯環境的乙個結構體,使其能夠在脫離上下文時仍然照常執行,並且不受外部的干擾。

從字面上理解,閉包就是將函式封閉、打包(中華文化博大精深,閉包這兩個字明顯比 Closure 更加貼切):封閉使其具有不被外界干擾的私有性,外部環境無法修改或直接訪問閉包中的資料;打包使其即使脫離了外部環境也能照常執行,他將所有自己執行所需的外部資料都打包進自己的空間。

而獲得閉包的方式,就是將函式以值的形式返回出來。

5樓:

不廢話。

Closure和Lexical Scope是相輔相成的兩個概念,伴隨高階函式(higher order function)而誕生。

什麼是高階函式?函式可以作為函式的引數就是高階函式的體現。

因為函式可以被當作值傳遞,這就又引出了兩個問題:

定義乙個函式f,f裡引用了乙個變數x,x在scope1裡。那麼當這個f被當作值傳遞到scope2時,如果這個scope2裡又有乙個x,這時evalulate這個函式,f裡引用的x是哪個scope裡的x

Lexical Scope告訴我們引用的是scope1裡的x。Dynamic Scope告訴我們引用的是scope2裡的x

如果我們的語言是Lexical Scope的,那麼如果這個scope1沒了怎麼辦?比如這個scope1就是乙個函式g:

defg

():x=1

deff

():print

("x is",x

)return

fClosure告訴我們,函式不僅包含code,還包含函式的執行環境。

6樓:沈鑫

這個問題其實沒有那麼複雜,記住兩點就行。

1.閉包就是函式內部能訪問函式外部的變數。

2.能訪問的外部變數只能是定義函式時在同乙個生命週期的變數,執行時在同一生命週期不能訪問

7樓:Eric AI

正常函式關注最後結果,函式執行完所有的內部變數都死了。閉包關注過程,把過程中產生的變數一併記在記憶體裡,方便未來可能的重用。

舉個例子,函式就像我走進了阿拉丁神燈的山洞裡,拿了乙個神燈出來,一出來這個山洞就塌了,我再也回不去了,我也想不起來這個山洞在哪,我探險的所有結果就是個神燈,但你問我這哪來的,我能告訴你,我在裡面有多危險才得到了麼,不能,因為我忘了!。閉包就是我歷經千辛萬苦獲得了神燈,並且出來了,我還能知道山洞的位置,我知道我在裡面是如何歷險的,並且我還能回去再拿點東西。

這就是區別,而且這也是函式式程式設計的部分體現,因為我們關注的是過程,而不再是返回值這種單值。

8樓:eita

「真正的閉包概念,實際上是乙個橫跨數學、邏輯、和計算和語言學的基礎概念,乙個近似哲學的概念。因此,從深層次理解閉包概念,不僅僅是就學習Lisp高階特性的重點,也是理解邏輯和計算關係、研究語言學理論的必要條件。」

引用自談談【閉包】概念——從《Let over Lambda》說開去

9樓:

A closure is the combination of a function and the lexical environment within which that function was declared.

10樓:PyCode

函式的執行會生成相應的執行環境,如果正常執行完函式,這個執行環境也就不能再被訪問到了,彷彿乙個「封閉的內部環境」。

但是如果提供一種在執行完後依然可以訪問這個執行環境的手段。比如返回函式,各種模組的做法等等。也就形成「閉包」。

這也是 《你不知道的js>中總結的那句,閉包即是一種引用。(此句有些省略,記不清了。。)

11樓:蜥蜴的尾巴

當倚天劍和屠龍刀(外部函式)相互對砍消毀後,裡面的武功秘籍(內部函式)流傳了出來。從今以後世人再也看不到倚天劍和屠龍刀(外部函式結束呼叫被銷毀),但是武功秘籍卻在某個角落裡藏著(在記憶體中不會銷毀),但是也很難再找到。

閉包就是武功秘籍(內部函式)記載了降龍十八掌,arguments等內容

12樓:

可以理解為暴露乙個方法讓外界來訪問函式內部原本不能訪問的內容,如:

function cc(fn)}

13樓:一夢千尋

如果說C++式的物件導向程式設計是把一組函式繫結到特定資料型別上的話,那麼閉包可以說是把一組資料繫結到特定函式上。 -- 引用雲風部落格

14樓:林側

通俗地講就是別人家有某個東西,你想拿到但是因為許可權不夠(不打死你才怪),但是你可以跟家裡的孩子套近乎,通過他拿到!

這個家就是區域性作用域,外部無法訪問內部變數,孩子是返回物件,對家裡的東西有訪問許可權,借助返回物件間接訪問內部變數!

15樓:slashhuang

這種問題在逼乎都快問爛了。

閉包這玩意就是function遵循lexical scoping的模式對它定義時的scope的乙個複製。

它不依賴於call stack,scope的訪問完全依賴它被定義時的位置。

解釋的通俗了吧( ▽` )

16樓:Sayako Hoshimiya

[Rudin 64]

嗯我故意的。

[Rudin 64] Rudin, Walter. Principles of mathematical analysis. Vol.

3. New York: McGraw-hill, 1964.

17樓:張海藍

danceblue大神的經典解釋:內部函式能用外部函式的變數,外部函式不能直接呼叫內部函式變數,這麼個情況就叫閉包,而且這個詞挺扯淡的……

18樓:小生

閉包的實現原理是在運用作用域鏈,去讓乙個函式可以使用另乙個函式中定義的變數而已。

其中有兩個重要的使用方法;

1. 函式作為返回值

全域性作用域function fnvar max = 10;//fn作用域return function bar(xif(x > max) //bar作用域console.log(xvar f1 = fn(); //將fn()函式賦值給f1max=100f1(15);

2. 函式作為引數被傳遞

var max = 10var fn = function(xif(x > maxconsole.log(xfunction(fvar max = 100f(15fn);

以上與君共勉

19樓:野山椒雞雜

乙個定義在函式(A)內部的函式(B),通過訪問這個內部函式(B)來獲取函式(A)內部的變數,函式(B)就是閉包/***閉包本身就是一種函式***/。閉包就是用來連線函式(A)內部與外部的橋梁。

20樓:

網上這些人啊,非要把簡單問題複雜化。

名字已經很清楚了,封閉的乙個包。僅此而已。

為什麼這麼重要?因為js沒有private關鍵字。

完全是為語言弱點擦屁股,靈活個屁。

21樓:郭寬

閉包(Closure)是一種把「生成自身時的環境「完全快照(Snapshot)儲存下來的物件,這個被生成的物件可以是乙個函式,當然可以被賦值給其他變數,如果沒有任何變數引用這個閉包,那麼它也會被向其他物件一樣被銷毀。

22樓:

閉包我的理解是在函式定義時,將乙個變數的作用域放到乙個封閉的容器內,在執行時該變數作為自由變數,通過作用域鏈可以訪問到的技術。。。

23樓:

The smallest object that both includes the object as a subset and possesses some given propertyPS:

javascript 閉包是怎麼回事?

Mine Allen 閉包是指有權訪問另乙個函式作用域中的變數的函式。也就是說,閉包 是乙個函式,這個函式可以有權訪問另乙個函式作用域中的變數。建立閉包的常用方法就是 在乙個函式內部建立另乙個函式。為什麼要說一下閉包呢?因為閉包和作用域鏈有著親密關係。逃 閉包之所以能夠訪問上一級函式的變數,就是因為...

rust怎麼閉包資料

stan4515 補充一下,目前已經有部分工具從node遷移到了rust,但目前正在遷移的工具大量依賴iterator,遷移的目是使用rust的交叉編譯,我們後端拒絕安裝node環境。另外目前的感覺是rust在函式式的支援上比js稍差些。大概要實現下邊的效果,但編譯報錯cannot move out...

js 閉包輸出問題?

木斯拉 個人猜測,第乙個沒用物件的方法時候,age因為在被包函式內,所以只能取得包含函式的活動變數的最後乙個值,而這個值一直是100,age 後的值並不能新增到時候包含函式作用域裡,而第二個採用物件方法,age一直在物件的作用域內,所以他會不斷加一。這是新手,錯了就刪。 box 會把age 100 ...