1.什么是閉包
廣義的說(shuō)嫡秕,一個(gè)變量一個(gè)函數(shù)就形成了一個(gè)閉包丸凭,典型的說(shuō):一個(gè)父函數(shù),返回一個(gè)子函數(shù)茵瀑,子函數(shù)調(diào)用父元素的局部變量间驮,所以父函數(shù)的內(nèi)存不能夠釋放,所以可以拓展了作用域马昨。
借用于阮一峰老師的話:閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù) 鏈接地址
芳姐的閉包理解「函數(shù)」和「函數(shù)內(nèi)部能訪問(wèn)到的變量」(也叫環(huán)境)的總和竞帽,就是一個(gè)閉包。鏈接地址
![簡(jiǎn)單的閉包](https://pic4.zhimg.com/v2-2d16967becf2df18358d62a84d0595e7_b.png)
簡(jiǎn)單的閉包
2.經(jīng)典的閉包解析
var fn = function (){
var local = "hello"
function say(){
return local
}
return say
}
解析
- 有時(shí)候看到在閉包中有立即執(zhí)行函數(shù)鸿捧,但是這個(gè)不是必須的屹篓,2個(gè)不同的概念不好弄混
為了省略一個(gè)變量的申明,我可以用一個(gè)立即執(zhí)行函數(shù)
(function(){
var local ='hello';
function say(){
return local
}
return say
})()
- 為什么要
return
一個(gè)函數(shù)呢匙奴?
如果不返回return堆巧,我們?cè)趺丛L問(wèn)這個(gè)變量,閉包的作用就是隱藏變量的同時(shí)泼菌,又可以訪問(wèn)到這個(gè)變量谍肤,如果不return,我們可以用window來(lái)得到
(function(){
var local ='hello';
window.say = function (){
local= local + 'world'
return local;
}
})()
這樣也是一個(gè)閉包哗伯,一個(gè)函數(shù)訪問(wèn)了其他函數(shù)的局部變量荒揣。
3. 閉包的經(jīng)典運(yùn)用
- 修改代碼讓fnArri 輸出 i
var fnArr = [];
for (var i = 0; i < 10; i ++) {
fnArr[i] = function(){
return i;
};
}
console.log( fnArr[3]() );
主要是當(dāng)我們?cè)谡{(diào)用的時(shí)候,js加載完成焊刹,此時(shí)i存放在全局變量中系任,循環(huán)結(jié)束后的值是10,所以會(huì)一直輸出10
方法一:立即執(zhí)行函數(shù)和閉包
var fnArr = [];
for(var i =0;i<10;i++){
fnArr[i]=(function (){
var n =i
return function(){
return n;
};
})(i)
}
簡(jiǎn)化
var fnArr = [];
for(var i =0;i<10;i++){
fnArr[i]=(function (n){
return function(){
return n;
};
})(i)
}
var fnArr = [];
for(var i =0;i<10;i++){
fnArr[i]=(function (){
var n=i
return function(){
return n;
};
})() //這里不用傳遞參數(shù)
}
方法二: 閉包
var fnArr = [];
for(var i =0;i<10;i++){
(function (){
var n = i;
fnArr[i]=function (){
return n
}
})()
}