閉包的簡樸明白

重要分三部分辯:
一、什麼是閉包?二、閉包有什麼優點?運用在那裡?

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);
    原文作者:名字不能缺
    原文地址: https://segmentfault.com/a/1190000014898717
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞