JS閉包是什么?
首先,放一個概念:
? ? ?函數 ?加 ?函數內部能訪問到的局部變量 ? 就組成了一個閉包
那閉包又有什么作用呢?
閉包常常用來「間接訪問一個變量」。換句話說,「隱藏一個變量」。
通常做法是 暴露一個訪問器(函數),讓別人可以「間接訪問」那個變量。
有這樣一段代碼:
var i = 'i am in windows'
var test = function(){
? ? ?var a = 0;
? ? ? var ?b = function(){?
? ? ? ? ? ?console.log(a)
? ? ? ?}
? ? ? ?return b
}
很明顯 a 是 test 這個函數對象內的局部變量 ?而在其內部 ?b 又引用了這個對象a ?這就是一個閉包
a變量 和 b 函數對象組成了一個閉包
那為什么要test函數里要再套一個b函數呢?
是因為需要局部變量,所以才把 a 放在一個函數里,如果不把 a 放在一個函數里,a 就是一個全局變量了,達不到使用閉包的目的——隱藏變量。
有些人看到「閉包」這個名字,就一定覺得要用什么包起來才行。其實這是翻譯問題,閉包的原文是 Closure,跟「包」沒有任何關系。
所以函數套函數只是為了造出一個局部變量,跟閉包無關。
那為什么又要 return b 呢?
因為如果不 return,你就無法使用這個閉包。return b 的目的只是讓外面可以訪問到這個 b 函數。
所以 return b 只是為了 b 能被使用,也跟閉包無關。
下面看下 ?閉包的廬山真面目:
看到了嗎? ? function scope 里面出現了Closure 和 Global?
Closure里有 a 變量的值? 也就是 0?
那么我們是否可以猜測? 我們在首行定義的全局變量 i 是不是就在Global這個 function scope 里面?
驗證下
全局變量 i 確實就在 Global里面
其實,function scope內默認有個名為 Globe 的全局引用(有了這個引用,就可以直接調用 Globe 的屬性或方法)
而在Closure里的變量或方法 外部是無法直接訪問的
這就是 隱藏 ?了一個變量
by ?潘小閑
參考資料: