1.定義:函數(shù)內(nèi)部的函數(shù)形成閉包
2.作用:一個(gè)是讀取函數(shù)中的變量嗅绸,另外一個(gè)是將函數(shù)中的變量存儲于內(nèi)存中
3.弊端:閉包會導(dǎo)致函數(shù)運(yùn)行結(jié)束后局部變量的空間不會被釋放從而造成內(nèi)存泄漏
注意:
(1)閉包里面使用局部變量和函數(shù)傳參的時(shí)候,用的就是外部函數(shù)的局部變量
(2)函數(shù)只是在被調(diào)用的時(shí)候會占用一定的內(nèi)存空間,所有在函數(shù)內(nèi)部定義的變量瞻惋,都在函數(shù)申請的這塊空間內(nèi)暫存,函數(shù)運(yùn)行完畢票顾,空間就被系統(tǒng)收回
4.函數(shù)執(zhí)行次數(shù)和閉包:函數(shù)調(diào)用的次數(shù)越多森爽,占用內(nèi)存越多,結(jié)合閉包以后就會造成內(nèi)存泄漏
例:函數(shù)執(zhí)行兩次嘀粱,保存的a不相同
function fn(){
var a = 10;
return function(){
console.log(++a);
}
}
var f1 = fn();//f1調(diào)用激挪,申請空間保存a,此時(shí)a是10,再次調(diào)用f1,a變成11,a++
var f2 =fn();//f2調(diào)用锋叨,再次申請空間保存a垄分,a開始還是10,再次調(diào)用f2時(shí),a才會在此基礎(chǔ)上增加
f1();//11
f1();//12
f1();//13
f1();//14
f2();//11
例:函數(shù)執(zhí)行一次娃磺,返回兩個(gè)值薄湿,產(chǎn)生的a是同一個(gè)
function fn(){
var a =10;
function in1(){
console.log(++a);
}
function in2(){
console.log(++a);
}
return [in1,in2]
}
var arr =fn(); //fn只調(diào)用一次
var f1=arr[0]; //f1保存in1這個(gè)函數(shù)
var f2=arr[1]; //f2保存in2這個(gè)函數(shù)
f1(); //11
f1();//12
f1();//13
f1();//14
f1();//15
f2()
-
注意:
(1)函數(shù)傳參閉包的運(yùn)用等同于在外部函數(shù)內(nèi)定義一個(gè)變量function fn(num){ return function(){ console.log(++num); } } var f1 = fn(10); var f2 = fn(10); f1(); // 11 f1(); // 12 f1(); // 13 f1(); // 14 f1(); // 15 f2(); // 16
(2)如果使用的是全局變量
var i =1;
function fn(){
return function(){
console.log(i++);
}
}
var f1 =fn();
var f2=fn();
f1(); //2
f1(); //3
f1(); //4
f1(); //5
f1(); //6
f2(); //7
// 由于i是全局變量,所以自始至終函數(shù)都是同一個(gè)i
閉包實(shí)例:點(diǎn)擊div打印對應(yīng)的下標(biāo),閉包實(shí)現(xiàn)
原理:自執(zhí)行函數(shù)里面的點(diǎn)擊方法會形成閉包,隨著for循環(huán)運(yùn)行10次豺瘤,函數(shù)也會運(yùn)行10次吆倦,每次tt運(yùn)行的時(shí)候,會有一個(gè)和變量a,然后每一個(gè)閉包保存了函數(shù)t運(yùn)行時(shí)候的變量a
for(var i=0;i<items.length;i++){
(function(){
var a =i;
items[i].click=function(){
console.log(a)
}
})()
}
等同于:
for(var i=0;i<items.length;i++){
(function(a){
var a =i;
items[i].click=function(){
console.log(a)
}
})(i);
}