為什么寫這篇文章:網(wǎng)上關(guān)于閉包的解釋五花八門鸦采,很多人自己往往也未清楚閉包宾巍,就嘗試用蹩腳的語言去描述它,而閉包是一個相對抽象的赖淤、跨越語言的概念蜀漆,網(wǎng)上的這些說法往往夾帶了JS的私貨。所以本篇是我整理的三點(diǎn)關(guān)于閉包的權(quán)威資料咱旱,并沒有自己的私貨确丢。下面的資料有一些有趣的分歧,如果你發(fā)現(xiàn)了并且有興趣與我探討一下吐限,歡迎聯(lián)系我鲜侥。
一、MDN
英文版:
Closures are functions that refer to independent (free) variables (variables that are used locally, but defined in an enclosing scope). In other words, these functions 'remember' the environment in which they were created.
中文版:
Closures (閉包)是使用被作用域封閉的變量诸典,函數(shù)描函,閉包等執(zhí)行的一個函數(shù)的作用域。通常我們用和其相應(yīng)的函數(shù)來指代這些作用域狐粱。(可以訪問獨(dú)立數(shù)據(jù)的函數(shù))
閉包是指這樣的作用域舀寓,它包含有一個函數(shù),這個函數(shù)可以調(diào)用被這個作用域所封閉的變量肌蜻、函數(shù)或者閉包等內(nèi)容互墓。通常我們通過閉包所對應(yīng)的函數(shù)來獲得對閉包的訪問。
二蒋搜、IBMdeveloperworks
閉包并不是什么新奇的概念篡撵,它早在高級語言開始發(fā)展的年代就產(chǎn)生了。閉包(Closure)是詞法閉包(Lexical Closure)的簡稱豆挽。對閉包的具體定義有很多種說法育谬,這些說法大體可以分為兩類:
一種說法認(rèn)為閉包是符合一定條件的函數(shù),比如參考資源中這樣定義閉包:閉包是在其詞法上下文中引用了自由變量(注1)的函數(shù)帮哈。
另一種說法認(rèn)為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實(shí)體膛檀。比如參考資源中就有這樣的的定義:在實(shí)現(xiàn)深約束(注2)時,需要創(chuàng)建一個能顯式表示引用環(huán)境的東西,并將它與相關(guān)的子程序捆綁在一起宿刮,這樣捆綁起來的整體被稱為閉包互站。
這兩種定義在某種意義上是對立的,一個認(rèn)為閉包是函數(shù)僵缺,另一個認(rèn)為閉包是函數(shù)和引用環(huán)境組成的整體胡桃。雖然有些咬文嚼字,但可以肯定第二種說法更確切磕潮。閉包只是在形式和表現(xiàn)上像函數(shù)翠胰,但實(shí)際上不是函數(shù)。函數(shù)是一些可執(zhí)行的代碼自脯,這些代碼在函數(shù)被定義后就確定了之景,不會在執(zhí)行時發(fā)生變化,所以一個函數(shù)只有一個實(shí)例膏潮。閉包在運(yùn)行時可以有多個實(shí)例锻狗,不同的引用環(huán)境和相同的函數(shù)組合可以產(chǎn)生不同的實(shí)例。所謂引用環(huán)境是指在程序執(zhí)行中的某個點(diǎn)所有處于活躍狀態(tài)的約束所組成的集合焕参。其中的約束是指一個變量的名字和其所代表的對象之間的聯(lián)系轻纪。那么為什么要把引用環(huán)境與函數(shù)組合起來呢?這主要是因?yàn)樵谥С智短鬃饔糜虻恼Z言中叠纷,有時不能簡單直接地確定函數(shù)的引用環(huán)境刻帚。這樣的語言一般具有這樣的特性:
函數(shù)是一階值(First-class value),即函數(shù)可以作為另一個函數(shù)的返回值或參數(shù)涩嚣,還可以作為一個變量的值崇众。
函數(shù)可以嵌套定義,即在一個函數(shù)內(nèi)部可以定義另一個函數(shù)航厚。
三丶?xì)v史上閉包的第一次定義
閉包這個概念第一次出現(xiàn)在1964年的《The Computer Journal》上顷歌,由P. J. Landin在《The mechanical evaluation of expressions》一文中提出了applicative expression和closure的概念。
文中AE的概念定義如下:
We are, therefore, interested in a class of expressions about any one of which it is appropriate to ask the following questions:
Q1. Is it an identifier? If so, what identifier?
Q2. Is it a λ-expression? If so, what identifier or identifiers constitute its bound variable part and in what arrangement? Also what is the expression constituting its λ-body?
Q3. Is it an operator/operand combination? If so, what is the expression constituting its operator? Also what is the expression constituting its operand?
We call these expressions applicative expressions (AEs).
在AE的基礎(chǔ)上幔睬,閉包定義為:
Also we represent the value of a λ-expression by a bundle of information called a "closure", comprising the λ-expression and the environment relative to which it was evaluated. We must therefore arrange that such a bundle is correctly interpreted whenever it has to be applied to some argument. More precisely:
a closure has an environment part which is a list whose two items are:
(1) an environment
(2) an identifier or list of identifiers
and a control part which consists of a list whose sole item is an AE.
結(jié)語
本篇中一共摘取了三點(diǎn)資料衙吩,前兩點(diǎn)中閉包都是跟JS有少許混雜的,或者說跟lexical scope(詞法作用域)少許混雜的溪窒。想要認(rèn)識閉包的本質(zhì),還需要理解提出閉包的這篇的論文冯勉。所以下篇我會研讀一下《The mechanical evaluation of expressions》中純粹的 Closure澈蚌,敬請期待。