我們經常在做前端面試題的時候,會遇到循環綁定事件後,輸出列印結果,很多人總是搞不清楚,今天借此機會跟大家梳理一下閉包相關作用。
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);
這種寫法,就很好的保護了空間變量,不會污染到外面的對象,所有的操作都在閉包内部執行。
以上隻是個人前端對于閉包的經驗之談,每個人了解的可能不一樣,有不對的地方,可指出來,我加以修正,謝謝。