我們經常在做前端面試題的時候,會遇到循環綁定事件后,輸出打印結果,很多人總是搞不清楚,今天借此機會跟大家梳理一下閉包相關作用。
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
使用閉包后:
function func1(){
var n=999;//局部變量,外部函數無法訪問
function func2(){
alert(n);
}
return func2;//返回內部函數
}
var result=func1();
result(); // 999
此時,可借助於閉包訪問f1函數的內部變量n,這就是閉包的功效之一,可以訪問某函數的局部變量。
B:防止空間污染。閉包中的變量不會被外界訪問,因而,內部和外部是隔斷的,從而減少變量重復帶來的困惑。
閉包的不好之處:
如果閉包引用外部變量,則此變量會一直存在於內存當中,從而降低性能,這也就是為什么,使用閉包循環綁定事件后,點擊會彈出對應數字的效果了。
另外,很多Jquery插件再開發的過程中,都會使用閉包,如下:
(function($){ //to-do ...
})(jQuery);
這種寫法,就很好的保護了空間變量,不會污染到外面的對象,所有的操作都在閉包內部執行。
以上只是個人前端對於閉包的經驗之談,每個人理解的可能不一樣,有不對的地方,可指出來,我加以修正,謝謝。