天天看點

JavaScript利用閉包循環綁定事件

  

我們經常在做前端面試題的時候,會遇到循環綁定事件後,輸出列印結果,很多人總是搞不清楚,今天借此機會跟大家梳理一下閉包相關作用。

1.首先我們舉一個簡單的例子。

html部分:

<a href="#">首頁</a>

<a href="#">作品</a>

<a href="#">文章</a>

<a href="#">工具</a>

<a href="#">招聘</a>

<a href="#">賽事</a>

<a href="#">更多</a>

js部分:

var a = document.getElementsByTagName("a");
for(var i =0; i<a.length; i++){ 
   a[i].onclick = function(){
        alert(i);
   }
}      

現在如果點選“首頁”連結,大家認為會彈出什麼數字? 答案是7,因為循環綁定以後,i最終為7,是以列印出來的結果就是 7 

2.下面我們使用閉包進行封裝一次。

var a = document.getElementsByTagName("a");
for(var i =0; i<a.length; i++){ 
   a[i].onclick = (function(i){
        return function(){alert(i);}
   })(i);
}      

此時,再次進行測試,點選超連結以後,彈出對應的索引值,這就是閉包的作用之一,閉包引用外部變量後,暫時不會被系統回收,onclick後面的代碼即為:立即執行一個函數,并且将i變量傳遞進去,執行函數的時候,内部傳回了一個函數,同時,傳回的函數内部會引用該參數,因而鎖定了此變量。當年點選某一個a連結時,就會執行此return 後面的函數,彈出對應的結果。

閉包簡單的說,就是方法裡面套方法,最終形成閉包,那麼經過我個人的總結經驗,閉包的作用主要有:

A:使用閉包可以通路某函數的局部變量,同時這些變量都一直存在于記憶體中。例如:

function func1(){

  var n=999;

}

alert(n); // error

使用閉包後:

  var n=999;//局部變量,外部函數無法通路

  function func2(){

    alert(n); 

  }

  return func2;//傳回内部函數

var result=func1();

result(); // 999

此時,可借助于閉包通路f1函數的内部變量n,這就是閉包的功效之一,可以通路某函數的局部變量。

B:防止空間污染。閉包中的變量不會被外界通路,因而,内部和外部是隔斷的,進而減少變量重複帶來的困惑。

閉包的不好之處:

如果閉包引用外部變量,則此變量會一直存在于記憶體當中,進而降低性能,這也就是為什麼,使用閉包循環綁定事件後,點選會彈出對應數字的效果了。

另外,很多Jquery插件再開發的過程中,都會使用閉包,如下:

(function($){
    //to-do ...
})(jQuery);
這種寫法,就很好的保護了空間變量,不會污染到外面的對象,所有的操作都在閉包内部執行。

以上隻是個人前端對于閉包的經驗之談,每個人了解的可能不一樣,有不對的地方,可指出來,我加以修正,謝謝。