JS閉包是什么坝撑?
首先,放一個(gè)概念:
? ? ?函數(shù) ?加 ?函數(shù)內(nèi)部能訪問(wèn)到的局部變量 ? 就組成了一個(gè)閉包
那閉包又有什么作用呢?
閉包常常用來(lái)「間接訪問(wèn)一個(gè)變量」巡李。換句話說(shuō)抚笔,「隱藏一個(gè)變量」。
通常做法是 暴露一個(gè)訪問(wèn)器(函數(shù))击儡,讓別人可以「間接訪問(wèn)」那個(gè)變量塔沃。
有這樣一段代碼:
var i = 'i am in windows'
var test = function(){
? ? ?var a = 0;
? ? ? var ?b = function(){?
? ? ? ? ? ?console.log(a)
? ? ? ?}
? ? ? ?return b
}
很明顯 a 是 test 這個(gè)函數(shù)對(duì)象內(nèi)的局部變量 ?而在其內(nèi)部 ?b 又引用了這個(gè)對(duì)象a ?這就是一個(gè)閉包
a變量 和 b 函數(shù)對(duì)象組成了一個(gè)閉包
那為什么要test函數(shù)里要再套一個(gè)b函數(shù)呢?
是因?yàn)樾枰植孔兞垦舻圆虐?a 放在一個(gè)函數(shù)里蛀柴,如果不把 a 放在一個(gè)函數(shù)里,a 就是一個(gè)全局變量了矫夯,達(dá)不到使用閉包的目的——隱藏變量鸽疾。
有些人看到「閉包」這個(gè)名字,就一定覺得要用什么包起來(lái)才行训貌。其實(shí)這是翻譯問(wèn)題制肮,閉包的原文是 Closure,跟「包」沒有任何關(guān)系递沪。
所以函數(shù)套函數(shù)只是為了造出一個(gè)局部變量豺鼻,跟閉包無(wú)關(guān)。
那為什么又要 return b 呢款慨?
因?yàn)槿绻?return儒飒,你就無(wú)法使用這個(gè)閉包。return b 的目的只是讓外面可以訪問(wèn)到這個(gè) b 函數(shù)檩奠。
所以 return b 只是為了 b 能被使用桩了,也跟閉包無(wú)關(guān)。
下面看下 ?閉包的廬山真面目:
看到了嗎? ? function scope 里面出現(xiàn)了Closure 和 Global?
Closure里有 a 變量的值? 也就是 0?
那么我們是否可以猜測(cè)? 我們?cè)谑仔卸x的全局變量 i 是不是就在Global這個(gè) function scope 里面埠戳?
驗(yàn)證下
全局變量 i 確實(shí)就在 Global里面
其實(shí)井誉,function scope內(nèi)默認(rèn)有個(gè)名為 Globe 的全局引用(有了這個(gè)引用,就可以直接調(diào)用 Globe 的屬性或方法)
而在Closure里的變量或方法 外部是無(wú)法直接訪問(wèn)的
這就是 隱藏 ?了一個(gè)變量
by ?潘小閑
參考資料: