摘要:要想保存在循環(huán)過程中每一個的值,需要在匿名函數外部再套用一個匿名函數,在這個匿名函數中定義另一個變量并且立即執(zhí)行來保存的值。這時最內部的匿名函數訪問的是的值,所以數組中個匿名函數的返回值就是。才是匿名函數功能執(zhí)行的環(huán)境。
閉包,有人說它是一種設計理念,有人說所有的函數都是閉包。我不知道如何去定義它,我也不準備去定義它,定義它就是限制了對它的理解。
我們依賴光來看清世間萬物,光卻遮住了黑暗。如同你腳下的路,讓你看不清前行的方向。
在這里寫一點我對閉包的理解。理解閉包的關鍵在于:外部函數調用之后其變量對象本應該被銷毀,但閉包的存在使我們仍然可以訪問外部函數的變量對象。
function outer() { var a = 1; return function() { return a; }; } var b = outer(); console.log(b()); //1模塊級作用域
(function(){ var now = new Date(); if (now.getMonth() == 0 && now.getDate() == 1) { alert("Happy new Year!"); } })();
這種方式常用來限制向全局作用域添加過多的變量和函數。
創(chuàng)建私有變量(funcion() { var a = 1; setA = function(val){ a = val; }; getA = function(){ return a; }; })(); console.log(a); //報錯 console.log(getA()); //1 setA(2); console.log(getA()); //2
也可以這樣寫:
function outer(){ var a = 1; return { setA: function(val) { a = val; }, getA: function() { return a; } }; } var closure = outer(); console.log(a); //報錯 console.log(closure.getA()); //1 closure.setA(2); console.log(closure.getA()); //2
第一個例子中,setA,getA都是全局變量,用于讀寫私有變量a。第二個例子中將這兩個方法作為一個對象返回并賦給一個全局變量closure,這樣當outer執(zhí)行完畢后,這兩個方法(匿名函數)連同外部函數中的變量對象(a)依然不會被銷毀。
閉包用于創(chuàng)建具有私有變量的實例對象,參考通過閉包創(chuàng)建具有私有屬性的實例對象
閉包只能取得包含函數中任何變量的最后一個值function arrFunc() { var arr = []; for (var i=0; i<10; i++) { arr[i] = function() { return i; }; } return arr; }
arr數組中包含了10個匿名函數,每個匿名函數都能訪問外部函數的變量i,那么i是多少呢?當arrFunc執(zhí)行完畢后,其作用域被銷毀,但它的變量對象仍保存在內存中,得以被匿名訪問,這時i的值為10。要想保存在循環(huán)過程中每一個i的值,需要在匿名函數外部再套用一個匿名函數,在這個匿名函數中定義另一個變量并且立即執(zhí)行來保存i的值。
function arrFunc() { var arr = []; for (var i=0; i<10; i++) { arr[i] = function(num) { return function() { return num; }; }(i); } return arr; } console.log(arrFunc()[1]()); //1
這時最內部的匿名函數訪問的是num的值,所以數組中10個匿名函數的返回值就是1-10。
閉包中的thisvar name = "window"; var obj = { name: "object", getName: function() { return function() { return this.name; }; } }; console.log(obj.getName()()); //window
obj.getName()()實際上是在全局作用域中調用了匿名函數,this指向了window。這里要理解函數名與函數功能是分割開的,不要認為函數在哪里,其內部的this就指向哪里。window才是匿名函數功能執(zhí)行的環(huán)境。要想使this指向外部函數的執(zhí)行環(huán)境,可以這樣改寫:
var name = "window"; var obj = { name: "object", getName: function() { var that = this; return function() { return that.name; }; } }; console.log(obj.getName()()); //object
arguments與this也有相同的問題。下面的情況也要注意:
var name = "window"; var obj = { name: "object", getName: function() { return this.name; } }; obj.getName(); //object (obj.getName = obj.getName)(); //window 非嚴格模式下
obj.getName();這時getName()是在對象obj的環(huán)境中執(zhí)行的,所以this指向obj。
(obj.getName = obj.getName)賦值語句返回的是等號右邊的值,在全局作用域中返回,所以(obj.getName = obj.getName)();的this指向全局。要把函數名和函數功能分割開來。
閉包會引用包含函數的整個變量對象,如果閉包的作用域鏈中保存著一個HTML元素,那么就意味著該元素無法被銷毀。所以我們有必要在對這個元素操作完之后主動銷毀。
function assignHandler() { var element = document.getElementById("someElement"); var id = element.id; element.onclick = function() { alert(id); }; element = null; }函數內部的定時器
當函數內部的定時器引用了外部函數的變量對象時,該變量對象不會被銷毀。
(function() { var a = 0; setInterval(function(){ console.log(a++); }, 1000); })();運用閉包的關鍵
閉包引用外部函數變量對象中的值;
在外部函數的外部調用閉包。
轉載請注明出處:https://segmentfault.com/a/1190000004585904
文章不定期更新完善,如果能對你有一點點啟發(fā),我將不勝榮幸。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/78871.html
摘要:也許最好的理解是閉包總是在進入某個函數的時候被創(chuàng)建,而局部變量是被加入到這個閉包中。在函數內部的函數的內部聲明函數是可以的可以獲得不止一個層級的閉包。 前言 總括 :這篇文章使用有效的javascript代碼向程序員們解釋了閉包,大牛和功能型程序員請自行忽略。 譯者 :文章寫在2006年,可直到翻譯的21小時之前作者還在完善這篇文章,在Stackoverflow的How do Java...
摘要:但是閉包也不是什么復雜到不可理解的東西,簡而言之,閉包就是閉包就是函數的局部變量集合,只是這些局部變量在函數返回后會繼續(xù)存在。可惜的是,并沒有提供相關的成員和方法來訪問閉包中的局部變量。 (收藏自 技術狂) 前言:還是一篇入門文章。Javascript中有幾個非常重要的語言特性——對象、原型繼承、閉包。其中閉包 對于那些使用傳統靜態(tài)語言C/C++的程序員來說是一個新的語言特性。本文將...
摘要:當在中調用匿名函數時,它們用的都是同一個閉包,而且在這個閉包中使用了和的當前值的值為因為循環(huán)已經結束,的值為。最好將閉包當作是一個函數的入口創(chuàng)建的,而局部變量是被添加進這個閉包的。 閉包不是魔法 這篇文章使用一些簡單的代碼例子來解釋JavaScript閉包的概念,即使新手也可以輕松參透閉包的含義。 其實只要理解了核心概念,閉包并不是那么的難于理解。但是,網上充斥了太多學術性的文章,對于...
摘要:一言以蔽之,閉包,你就得掌握。當函數記住并訪問所在的詞法作用域,閉包就產生了。所以閉包才會得以實現。從技術上講,這就是閉包。執(zhí)行后,他的內部作用域并不會消失,函數依然保持有作用域的閉包。 網上總結閉包的文章已經爛大街了,不敢說筆者這篇文章多么多么xxx,只是個人理解總結。各位看官瞅瞅就好,大神還希望多多指正。此篇文章總結與《JavaScript忍者秘籍》 《你不知道的JavaScri...
摘要:但是,必須強調,閉包是一個運行期概念。通過原型鏈可以實現繼承,而與閉包相關的就是作用域鏈。常理來說,一個函數執(zhí)行完畢,其執(zhí)行環(huán)境的作用域鏈會被銷毀。所以此時,的作用域鏈雖然銷毀了,但是其活動對象仍在內存中。 學習Javascript閉包(Closure)javascript的閉包JavaScript 閉包深入理解(closure)理解 Javascript 的閉包JavaScript ...
摘要:閉包的注意事項通常,函數的作用域及其所有變量都會在函數執(zhí)行結束后被銷毀。但是,在創(chuàng)建了一個閉包以后,這個函數的作用域就會一直保存到閉包不存在為止。最后通過釋放了和對閉包的引用。從而使用閉包模塊化代碼,減少全局變量的污染。 JavaScript 閉包 原文鏈接 什么是閉包(Closure) 簡單講,閉包就是指有權訪問另一個函數作用域中的變量的函數。 MDN 上面這么說:閉包是一種特殊的...
閱讀 3915·2021-11-16 11:50
閱讀 927·2021-11-11 16:55
閱讀 3659·2021-10-26 09:51
閱讀 856·2021-09-22 15:03
閱讀 3409·2019-08-30 15:54
閱讀 3260·2019-08-30 15:54
閱讀 2468·2019-08-30 14:04
閱讀 919·2019-08-30 13:53