
閉包的定義
閉包 是指有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域中的變量的函數(shù)。(JS高級(jí)程序設(shè)計(jì))
看到這紅寶書(shū)上關(guān)于閉包的解釋?zhuān)鸪跻荒樸卤疲x懂之后其實(shí)并不難。要徹底了解閉包,首先必須了解下面的幾個(gè)概念:
執(zhí)行環(huán)境:每個(gè)函數(shù)都有自己的執(zhí)行環(huán)境。當(dāng)執(zhí)行函數(shù)時(shí),函數(shù)的環(huán)境就會(huì)被推入一個(gè)環(huán)境棧中。而在函數(shù)執(zhí)行后,棧將其環(huán)境彈出,把控制權(quán)返回給之前的執(zhí)行環(huán)境。
變量對(duì)象:每個(gè)執(zhí)行環(huán)境都有一個(gè)與之關(guān)聯(lián)的變量對(duì)象,環(huán)境中定義的所有變量和函數(shù)都保存在這個(gè)對(duì)象中。當(dāng)執(zhí)行函數(shù)時(shí),變量對(duì)象會(huì)變成活動(dòng)對(duì)象。
作用域鏈:當(dāng)代碼在一個(gè)環(huán)境中執(zhí)行時(shí),會(huì)創(chuàng)建變量對(duì)象的一個(gè)作用域鏈。作用域鏈的用途,是
保證對(duì)執(zhí)行環(huán)境有權(quán)訪問(wèn)的所有變量和函數(shù)的有序訪問(wèn)。作用域鏈的前端,始終都是當(dāng)前執(zhí)行的代碼所
在環(huán)境的變量對(duì)象。如果這個(gè)環(huán)境是函數(shù),則將其活動(dòng)對(duì)象作為變量對(duì)象。
執(zhí)行環(huán)境和變量對(duì)象的概念容易理解,但是怎么理解作用域鏈呢??梢詤⒖枷聢D:

可以看成是同心圓結(jié)構(gòu),每一層假設(shè)是一個(gè)函數(shù),上面都擁有與此層函數(shù)關(guān)聯(lián)的變量對(duì)象;假設(shè)當(dāng)執(zhí)行到最里面那個(gè)函數(shù),那么作用域鏈可以看做是圖中一條由內(nèi)到外的線,最前端的就是它本身,最后端就是全局執(zhí)行環(huán)境。那么它有什么用呢,就是當(dāng)你訪問(wèn)一個(gè)變量的時(shí)候,就會(huì)沿著作用域鏈一層層往外查找,直到找到為止,如果到了最外層即全局執(zhí)行環(huán)境下還沒(méi)找到則報(bào)錯(cuò)。
閉包的實(shí)現(xiàn)
下面通過(guò)具體例子來(lái)解釋?zhuān)?/p>
function a() {
var text = '呵呵噠';
return function () {
console.log(text);
}
}
var b = a();
b();
當(dāng)a()函數(shù)被執(zhí)行后返回了一個(gè)匿名函數(shù),這個(gè)匿名函數(shù)的作用域鏈上有引用到a()執(zhí)行環(huán)境的活動(dòng)對(duì)象屬性text(不知道活動(dòng)對(duì)象是什么的請(qǐng)看上面變量對(duì)象的解釋?zhuān)?code>a()函數(shù)執(zhí)行完就馬上被銷(xiāo)毀了,但是這個(gè)函數(shù)的變量對(duì)象仍然被b所引用,所以它的變量對(duì)象不會(huì)被垃圾回收機(jī)制處理掉,而是會(huì)留在內(nèi)存中。這就形成了一個(gè)閉包。最后執(zhí)行b()依然能讀取到已經(jīng)被銷(xiāo)毀的a函數(shù)的定義的text變量。
我們換個(gè)更清晰的例子:
function a() {
var i = 0;
return function () {
console.log(i++);
}
}
var b = a();
b(); //0
b(); //1
b(); //2
這個(gè)例子三次調(diào)用b()會(huì)分別輸出0、 1、 2,是因?yàn)?code>a()的變量對(duì)象被return的閉包函數(shù)引用著,所以i會(huì)一直留在內(nèi)存中,并只能被閉包函數(shù)所訪問(wèn)。這個(gè)閉包函數(shù)被賦值給了b,所以b()能對(duì)i變量進(jìn)行自增計(jì)算。
閉包的作用
什么,你問(wèn)我閉包有什么用?
好處就是隱藏變量,然后搭起一條溝通的橋,閉包可以間接操作這個(gè)隱藏變量;并且讓這個(gè)變量留在內(nèi)存中而不會(huì)污染到全局變量。
壞處呢消耗內(nèi)存,如果一直不釋放這個(gè)閉包就會(huì)一直占用著內(nèi)存。那要怎么釋放呢?很簡(jiǎn)單,和函數(shù)一樣賦值null就可以了。(b = null)
最后感謝觀看~
我是@一只有趣的程序猿 我叫大友~