閉包的簡單理解

主要分三部分說:
1、什麼是閉包?2、閉包有什麼好處?應用在哪裏?javascript

一、什麼是閉包

第一個特色:能夠是函數嵌套函數html

function fna(){
       function fnb(){}
   }

第二個特色:內部函數能夠引用外部函數的參數和變量java

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的.這就是簡單的閉包形式。code

二、閉包的好處和應用

好處:
1.但願一個變量長期駐紮在內存當中
2.避免全局變量的污染htm

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:ip

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);
相關文章
相關標籤/搜索