本文實例講述了JavaScript閉包原理與用法。分享給大家供大家參考,具體如下:
1、與閉包有關的兩個概念:
1) 變量的作用域
不帶有關鍵字var的變量會成為全局變量;
在函數中使用關鍵字var聲明的變量是局部變量。
局部變量只有在函數內部才能訪問到,在函數外面是訪問不到的。但在函數內部可以通過作用域鏈一直向上搜索直到全局對象,也就是說,函數內部可以訪問函數外部的變量。
2) 變量的生存周期
對于全局變量,其生存周期是永久的,除非主動銷毀這個全局變量;
而對于在函數內用關鍵字var聲明的局部變量,當退出函數時,這些局部變量會隨著函數調用結束而被銷毀。
var func = function() { var i = 1; alert(i); // 輸出:1};alert(i); // 報錯:i is not defind.例外情況:閉包
var func = function() { var i = 1; return function() { alert(i); i++; }};var f1 = func();f1(); // 輸出:1f1(); // 輸出:2var f2 = func();f2(); // 輸出:1f2(); // 輸出:22、從閉包的一個經典應用談起
<div>0</div><div>1</div><div>2</div><div>3</div><div>4</div><script> var divs = document.getElementsByTagName("div"); for (var i = 0; i < divs.length; i++) { divs[i].onclick = function() { alert(i); }; }</script>問題:無論單擊哪個div,都會彈出5。
原因:onclick事件是異步觸發的,當事件被觸發時,for循環早已結束,此時變量i的值早已經是5。
解決:在閉包的幫助下,把每次循環的i值都封閉起來。當事件函數順著作用域鏈從內到外查找變量i時,會先找到被封閉在閉包環境的i,單擊div時,會分別輸出0,1,2,3,4。
<div>0</div><div>1</div><div>2</div><div>3</div><div>4</div><script>var divs = document.getElementsByTagName("div");for (var i = 0; i < divs.length; i++) { divs[i].onclick = (function(num) { return function() { alert(num); }; })(i);}</script>類似實例:閉包直接賦給數組
function createFunctions() { var result = new Array(); for (var i = 0; i < 10; i++){ result[i] = function(){ return i; }; } return result;}for (var i = 0; i < 10; i++) alert(createFunctions()[i]());結果:result的每個元素都返回10。
說明:閉包的作用域鏈有明顯的副作用——閉包總是獲得外部函數變量的最終值。上面代碼中,外部函數產生一個函數數組result并返回。函數數組中的每個元素都是一個函數,每個函數都返回 i變量。似乎每個函數應該返回每次循環的i值,即依次返回0到9,但事實是,每個函數的返回結果都是10。這是因為每個內部函數返回的是變量i,而不是i在某個時刻的特定值,而i的作用域是整個外部函數,當外部函數執行完成后,i的值是10。
新聞熱點
疑難解答
圖片精選