重要分三部分辯:
一、什麼是閉包?二、閉包有什麼優點?運用在那裡?
1、什麼是閉包
第一個特性:可所以函數嵌套函數
function fna(){
function fnb(){}
}
第二個特性:內部函數能夠援用外部函數的參數和變量
function fna(){
var b=5;
function fnb(){
console.log(b);
}
fnb();
}
fna();
b變量都要被內部函數fnb()援用到,會一向駐紮在內存中,不會被渣滓接納的,也就是說參數和變量不會被渣滓接納機制所收回。
那末什麼是js渣滓接納機制呢?
function fna(){
var a=1;
}
fna();
比方,上面寫了個一般函數fna(),當fna();實行終了后變量a就不存在了,為了節約內存。
例1:
function fna(){
var a=5;
function fnb(){
console.log(a);
}
return fnb;
}
var fnc=fna();
fnc(); //5
變量c就是返回的fnb函數,fnc()實行的時刻 變量a並沒有消逝,一向駐紮在內存中的,這時候會彈出5的.這就是簡樸的閉包情勢。
2、閉包的優點和運用
優點:
1.願望一個變量歷久駐紮在內存當中
2.防止全局變量的污染
var a=1;
function fna(){
a++;
console.log(a);
}
fna(); //2
fna(); //3
console.log(a);//3
a是個全局變量,一向駐紮在內存中,順次實行會累加。
function fna(){
var a=1;
a++;
console.log(a);
}
fna(); //2
fna(); //2
如果把變量a設置為局部變量,每挪用一次代碼從新實行,挪用后a就不存在,下次挪用的時刻a照樣1;那末怎麼能做到a等於局部變量,a又能累計呢?
這就是閉包所能做到的。
例2:
function fna(){
var a=1;
return function () {
a++;
console.log(a);
};
}
var fnb=fna();
fnb(); //2
fnb(); //3
console.log(a) //undfined
構成了函數嵌套函數,當表面的函數實行終了后,內部函數照舊能夠挪用到變量a;
(function(){
console.log(1);
})();
()放函數,函數聲明就會變成函數表達式,再加()馬上實行。
至此能夠把例2中的代碼改寫一下.
var fna= (function () {
var a=1;
return function () {
a++;
console.log(a);
}
})();
fna();//2
fna();//3
var a=1在表面是挪用不到,削減全局變量的污染,把內部函數變成私有的,
這也就是
3.變量私有
var aaa = (function(){
var a = 1;
function bbb(){
a++;
console.log(a);
}
function ccc(){
a++;
console.log(a);
}
return {
b : bbb,
c : ccc
}
})();
//aaa.b(); //2
//aaa.c(); //3
在輪迴中直接找到對應元素的索引
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul>
<li>11111111111</li>
<li>11111111111</li>
<li>11111111111</li>
</ul>
<script>
window.onload = function(){
var aLi = document.getElementsByTagName('li');
for(var i=0;i<aLi.length;i++){
aLi[i].onclick = function(){
console.log(i);//3
};
};
};
</script>
</body>
</html>
console.log(i)彈出3,為何呢?很明顯,當輪迴實行完畢的時刻
aLi[i].onclick = function(){
console.log(i);//3
};
還沒實行,當點擊的時刻才會實行,但此時i已變成3了。能夠應用閉包改寫,能夠把輪迴中的i看成個參數傳進去,就之前所說的內部函數能夠援用外部函數的參數和變量。
for(var i=0;i<aLi.length;i++){
(function(i){
aLi[i].onclick = function(){
console.log(i);
};
})(i);
把i當做參數穿進去。除了這類寫法另有別的一種體式格局
for(var i=0;i<aLi.length;i++){
aLi[i].onclick = (function(i){
return function(){
console.log(i);
}
})(i);