一、認識閉包
案例:
頁面有5個li標籤,標籤顯示0~4五個數字,點擊不同的標籤在控制檯中打印標籤的索引。
主要代碼:
<ul>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<script>
var liList=document.getElementsByTagName("li");
for(var i=0;i<liList.length;i++){
liList[i].onclick=function(){
console.log(i);
}
}
</script>
主要說明:
如果是你會不會這樣寫?
如果這樣寫,一旦運行就會發現不管點擊那個標籤打印的都是數字"5"。因爲在執行點擊操作時,for循環已經進行完畢且i值爲"5"。那怎麼做才能使每次循環時i值得以保存不被系統回收?閉包!
代碼修改:
<ul>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<script>
var liList=document.getElementsByTagName("li");
for(var i=0;i<liList.length;i++){
liList[i].onclick=(function(j){
return function(){
console.log(j);
}
})(i);
}
</script>
代碼說明:
當兩個函數發生嵌套,內部函數使用外部函數的變量或者參數就會形成閉包。形成閉包之後,內部函數的變量將會被保存在對應的函數內存中,不會像上面代碼中內部函數變量被及時清除。
二、閉包的定義
1.函數嵌套函數
2.內層函數訪問調用外層函數變量或參數(將參數或者變量長期保存在內存中)
三、閉包的作用
1.實現公有變量(函數累加器)
function add(){
var num = 0;
function a(){
console.log( ++ num);
}
return a;
}
var myadd = add();
myadd();//結果爲1
myadd();//結果爲2
myadd();//結果爲3
2.可以做緩存(存儲結構)
3.可以實現封裝,屬性私有化(私有化變量)
function Deng(name,wife){
var prepareWife = "xiaozhang";
this.name = name;
this.wife = wife;
this.divorce = function(){
this.wife = prepareWife;
}
this.changePrepareWife = function(target){
prepareWife = target;
}
this.sayPrepareWife = function(){
console.log(prepareWife);
}
}
var deng = new Deng('deng','xiaoliu');