對于初次步入代碼界的小朋友們,聽說閉包這個詞,感覺摸不著頭腦,所以本人親自整理了一下理解閉包的思路,本文主要是從三個反面闡述了閉包:1,什么是閉包;2閉包的好處以及應用;3,使用閉包需要注意什么。別的不多說了,直接上碼。
一,什么是閉包?
定義:函數嵌套函數,內部函數可以引用外部函數的參數和變量,變量和參數不會被垃圾回收機制所回收
例1:這是一個比較明顯的閉包
function show(a){ //外面的函數 a是參數(實質也是函數show的局部變量)
var b=12;//b是局部變量
function show1(){//里面的函數
console.log(a); //=》2 //里面的函數可以訪問到外面函數的參數和變量
console.log(b); //=》12
}
show1();
}
show(2);
例2:解釋一下垃圾回收機制
function aaa(){
var a=12;//a是局部變量
alert(a);
a++;
}
aaa();//=》 12
aaa();//=》 12
//執行2次aaa函數,彈出的結果都是12,說明變量a每執行一次,都會被垃圾回收機制所回收,重新調用的時候就會重新執行初始的代碼,如果寫成閉包的形式再來看一下:
function aaa(){
var a=12;
return function(){
alert(a);
a++;
}
}
var b=aaa();
b();//=》 12
b();//=》 13
//定義函數aaa的時候,形成了函數嵌套函數的閉包,其中的變量a在第一次執行b的時候不會被垃圾回收機制所回收,所以第一次出來結果是12,然后在此基礎是a++,再次執行時就變成了13。這個例子也說明的閉包的第一個好處,希望一個變量長期駐扎在內存之中
二,閉包有什么好處,應用在哪里
1,希望一個變量長期駐扎在內存之中(見例2)
2,避免全局變量的污染
例3:我們先來寫個全局變量,然后定義一個函數試一試
var a=12;
function show(){
alert(a);
a++;
}
show();//=》 12
show();//=》 13
alert(a);//全局變量最后變成了=》 14,顯然全局變量被污染了。
我們在寫成閉包的形式來看一下:
var a=12;
var b=(function(i){
return function(){
alert(i);
i++;
}
})(a)
b();//=》 12
b();//=》 13
alert(a);//全局變量依然是=》 12,沒有被污染
3,私有成員的存在
例4:
function show(){
var a=12;
function show1(){
alert(a);
a++;
}
function show2(){
alert(a);
a++;
}
return {show1:show1,show2:show2};
}
var b=show();//調用函數的返回值
b.show1();//=》 12
b.show2();//=》 13 兩次執行都是調用變量他們公共的變量a
alert(a)//報錯
alert(show1)//報錯
alert(show2)//報錯
//在這里需要知道函數本質其實是一個特殊的對象,函數里面的變量a,定義的函數show1和show2,都屬于函數的私有成員,在外面訪問不到會報錯。
應用:例2中的(function(){})()形式,就是閉包的一個典型的影響,我們可以稱作是封閉空間,也可說是模塊化代碼
三,使用閉包需要注意什么
使用有可能出現內存泄漏,在這里只是簡單說一下原理
例5:
window.onload=function(){
var oBtn=document.getElementById('btn');
oBtn.onclick=function(){
alert(oBtn.id)//btn
}
}
//此種形式也形成了函數嵌套函數的閉包形式,點擊按鈕oBtn的時候,變量oBtn的點擊事件得不到釋放,影響cpu的性能,導致內存泄漏,這個時候可以點擊之后,加oBtn.onclick=null;是變量oBtn的點擊時候得到釋放
注,閉包貫穿整個js,如果想徹底理解閉包很難,所以想深入理解閉包需要在工作中長期的沉淀積累,如果各位大神有更好的理解方式可以留言,我們共同探討