JavaScript 學(xué)習(xí)筆記之閉包
這篇文章是我學(xué)習(xí)閉包的筆記與總結(jié)碧库,后面會(huì)有一些例子,結(jié)合畫(huà)圖的形式來(lái)理解巧勤,什么是閉包…..如有錯(cuò)誤嵌灰,還望指正,大神勿噴……
從以下幾個(gè)方面去說(shuō)閉包
1. 什么是閉包
2. 為什么使用閉包
3. 何時(shí)使用閉包
4. 如何使用閉包
5. 閉包是如何形成的
6. 閉包的缺點(diǎn)
什么是閉包
其實(shí)閉包它并不是一種(類(lèi)似于對(duì)象)看得見(jiàn)摸得著的東西颅悉,它是一種機(jī)制沽瞭;
是一種:能夠讓你重復(fù)使用變量,而又不會(huì)造成變量污染
的機(jī)制
為什么要使用閉包
-
為什么使用閉包要從
全局變量和局部變量的優(yōu)缺點(diǎn)
說(shuō)起- 全局作用域:保存全局變量剩瓶,可以反復(fù)使用驹溃,而且隨處可用,但是會(huì)造成全局污染
- 局部作用域:保存局部變量延曙,僅函數(shù)內(nèi)可用豌鹤,而且不可反復(fù)使用
何時(shí)使用閉包
既要重用變量,又保護(hù)變量不被污染
如何使用閉包
外層函數(shù) 包裹受保護(hù)的變量和操作變量的內(nèi)層函數(shù)
-
外層函數(shù)要返回內(nèi)層函數(shù)枝缔,有 3 種返回方式:
- return function
- 直接給全局變量賦值一個(gè)內(nèi)部function
- 將內(nèi)部函數(shù)保存在一個(gè)對(duì)象的屬性或數(shù)組元素中
調(diào)用外層函數(shù)布疙,用全局變量接住返回的內(nèi)層函數(shù)的變量
(這一步形成閉包)
閉包如何形成
外層函數(shù)被調(diào)用后,外層函數(shù)的作用域?qū)ο?Active Object)愿卸,無(wú)法釋放灵临,被內(nèi)層函數(shù)(scope)引用著。
閉包的缺點(diǎn)
- 閉包比普通函數(shù)更占內(nèi)存趴荸,外層函數(shù)的作用域?qū)ο?AO)始終存在
- 造成內(nèi)存泄漏儒溉,解決的辦法(釋放閉包):將引用內(nèi)層函數(shù)對(duì)象的全局變量置為 null,導(dǎo)致內(nèi)層函數(shù)被釋放赊舶,導(dǎo)致外層函數(shù)的AO被釋放
最后在來(lái)舉幾個(gè)栗子:
1. 簡(jiǎn)單的例子
function factory () {
var num = 1;
return function () {
console.log( i++ );
}
}
var getNum = factory(); // => function ...
getNum(); // => ?
getNum(); // => ?
getNum(); // => ?
i++ ; // 污染
getNum(); // => ?
畫(huà)圖理解上述栗子
代碼運(yùn)行到紅線部分的時(shí)候睁搭,執(zhí)行環(huán)境棧中僅有一個(gè)全局執(zhí)行環(huán)境(window),此時(shí) window 中有兩個(gè)全局變量(標(biāo)識(shí)符):factory 笼平、getNum
此時(shí)的ESC中的活動(dòng)執(zhí)行環(huán)境為 factory园骆,在factory的AO中,有變量 num寓调,此時(shí)num的值為1. (綠色線條的關(guān)系就形成了閉包)
factoryECS出棧之后锌唾,由于getNum引用著 factory的內(nèi)層函數(shù),而內(nèi)層函數(shù)的scope也引用著factory,所以factory的活動(dòng)對(duì)象并沒(méi)有被釋放
當(dāng)getNum的EC進(jìn)棧之后晌涕,getNum的AO中并沒(méi)有num變量滋捶,所以會(huì)向父級(jí)進(jìn)行查找,找到之后console.log( num )余黎;并進(jìn)行++操作重窟;
[圖片上傳失敗...(image-a7be63-1530276074470)]
原理同上。
2. 鄙視面試題
function outer () {
for (var i = 0, arr = []; i < 3; i++) {
arr[i] = function () { console.log(i); }
}
return arr;
}
var ot = outer(); // => arr
ot[0](); // =>?
ot[1](); // =>?
ot[2](); // =>?
畫(huà)簡(jiǎn)圖理解: