閉包(Closure)是一個老生常談的話題外驱,也是JavaScript重要的特性之一(閉包和異步)
說閉包之前我們先了解下作用域(scopes)
作用域分為全局變量和局部變量刻剥。
在函數(shù)下定義var就會產(chǎn)生一個局部變量遮咖,否則就會創(chuàng)建一個全局變量。全局變量是一個定時炸彈造虏,要小心對待御吞。
可以開啟嚴格模式檢查 'use strict'
JavaScript有一個特性,外部的訪問不到內(nèi)部的漓藕,內(nèi)部可以訪問外部的陶珠。
var a = 0
;(function cope(){
var b = 1
console.log(a)// 0
})()
console.log(b)// defined
另一個作用域想要獲取內(nèi)部作用域變量,需要變通下享钞。
var a = 0
;(function cope(){
var b = 1
console.log(a)//0
;(function test(){
console.log(b)// 1
})()
})()
上面的代碼里揍诽,test嵌套在cope里面,test可以訪問cope里面的變量嫩与,那么就是閉包么寝姿,也許是吧,但確切說并不是划滋。
為什么說是饵筑,因為test嵌套在cope函數(shù)里面,test可以訪問到cope的代碼处坪。
為什么說不是根资,因為這只是滿足了一部分閉包的一部分規(guī)則,但這是最重要的同窘。
那什么是閉包
var c = (function(){
var _var = 0
function test(){
console.log(_var)
}
return test
})()
c()// 媽媽玄帕,你看這就是閉包
對比上面的代碼,有什么變化想邦? 對裤纹,就是return回去,然后實際調(diào)用丧没。
test函數(shù)在外部調(diào)用鹰椒,閉包可以繼續(xù)享受定義時的語法作用域锡移。
注意:閉包創(chuàng)建完之后,this是window
閉包可以有效防止變量沖突漆际,還有一個常用的是立即執(zhí)行函數(shù)(IIFE)
如上面的代碼
// 顯示函數(shù)請用(function(){})() 的寫法淆珊,不然外部調(diào)用不到
;!function(){
// lalalalalala
}()
我們利用IIFE來解決不希望copes發(fā)生的事情。
var arr = []
for(var i=0; i < 10; i++){
arr[i] = function(){
console.log(i)
}
}
arr[0]() // 10 納尼奸汇?媽媽施符,這是怎么回事?
媽媽:因為所有函數(shù)共享同一個[[Scope]]
試著用IIFE得到真確的值:
var arr = []
for(var i=0; i < 10; i++){
;(function(i){
arr[i] = function(){
console.log(i)
}
})(i)
}
arr[0]()
嚴格來說IIFE并不是閉包擂找。
寫一個柯里化玩玩
function a(){
var i = 0
function init(v){
i = v+i
console.log(i)
return init
}
return init
}
var a = a()
更多實例請看開源的庫戳吝,比如書生寫的XXY
如遇到錯誤,懇請批評指正婴洼,謝謝骨坑!
---END--