摘要:由于在語言中只有函數內部的子函數才能讀取局部變量,因此可以把閉包理解為定義在一個函數內部的函數。使用閉包的注意點由于閉包使函數中的變量都被保存在內存中,內存消耗很大,所以不能濫用閉包。當返回時,變量的值為,所有閉包都共享這一個值。
簡單點可以理解為:閉包就是能夠讀取其他函數內部變量的函數。由于在javascript語言中,只有函數內部的子函數才能讀取局部變量,因此可以把閉包理解為“定義在一個函數內部的函數”。
讀取函數內部的變量。
變量的值始終保持在內存中。
function f1(){ var n = 999; nAdd = function(){ n += 1 } function f2(){ console.log(n); } return f2; } var result=f1(); result(); // => 999 nAdd(); result(); // => 1000
在這段代碼中,result實際上就是閉包f2函數。它一共運行了兩次,第一次的值是999,第二次的值是1000。這證明了,函數f1中的局部變量n一直保存在內存中,并沒有在f1調用后被自動清除。
為什么會這樣呢?原因就在于f1是f2的父函數,而f2被賦給了一個全局變量,這導致f2始終在內存中,而f2的存在依賴于f1,因此f1也始終在內存中,不會在調用結束后,被垃圾回收機制(garbage collection)回收。
這段代碼中另一個值得注意的地方,就是"nAdd=function(){n+=1}"這一行,首先在nAdd前面沒有使用var關鍵字,因此nAdd是一個全局變量,而不是局部變量。其次,nAdd的值是一個匿名函數(anonymous function),而這個匿名函數本身也是一個閉包,所以nAdd相當于是一個setter,可以在函數外部對函數內部的局部變量進行操作。
由于閉包使函數中的變量都被保存在內存中,內存消耗很大,所以不能濫用閉包。解決方法:在退出函數之前,將不使用的局部變量全部刪除。閉包不會造成內存泄漏,內存泄漏是瀏覽器的bug。
閉包會在函數外部,改變父函數內部變量的值。
function constfuncs() { var funcs = []; for(var i = 0; i < 10; i++ ) { funcs[i] = function () { return i; } } return funcs; } var funcs = constfuncs(); console.log(funcs[5]()); // => 10
這段代碼創建了10個閉包,并將它們存儲到一個數組中。這些閉包都是在同一個函數中定義的,所以它們共享變量i。當constfuncs()返回時,變量i的值為10,所有閉包都共享這一個值。
修改為:
function constfuncs(v) { return function() { return v; } } var funcs = []; for(var i = 0; i < 10; i++ ) { funcs[i] = constfuncs(i); } console.log(funcs[5]()); // => 5
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/86311.html
摘要:閉包引起的內存泄漏總結從理論的角度將由于作用域鏈的特性中所有函數都是閉包但是從應用的角度來說只有當函數以返回值返回或者當函數以參數形式使用或者當函數中自由變量在函數外被引用時才能成為明確意義上的閉包。 文章同步到github js的閉包概念幾乎是任何面試官都會問的問題,最近把閉包這塊的概念梳理了一下,記錄成以下文章。 什么是閉包 我先列出一些官方及經典書籍等書中給出的概念,這些概念雖然...
摘要:當在中調用匿名函數時,它們用的都是同一個閉包,而且在這個閉包中使用了和的當前值的值為因為循環已經結束,的值為。最好將閉包當作是一個函數的入口創建的,而局部變量是被添加進這個閉包的。 閉包不是魔法 這篇文章使用一些簡單的代碼例子來解釋JavaScript閉包的概念,即使新手也可以輕松參透閉包的含義。 其實只要理解了核心概念,閉包并不是那么的難于理解。但是,網上充斥了太多學術性的文章,對于...
摘要:一言以蔽之,閉包,你就得掌握。當函數記住并訪問所在的詞法作用域,閉包就產生了。所以閉包才會得以實現。從技術上講,這就是閉包。執行后,他的內部作用域并不會消失,函數依然保持有作用域的閉包。 網上總結閉包的文章已經爛大街了,不敢說筆者這篇文章多么多么xxx,只是個人理解總結。各位看官瞅瞅就好,大神還希望多多指正。此篇文章總結與《JavaScript忍者秘籍》 《你不知道的JavaScri...
摘要:權威指南第版中閉包的定義函數對象可以通過作用域鏈相互關聯起來,函數體內部的變量都可以保存在函數作用域內,這種特性在計算機科學文獻中成為閉包。循環中的閉包使用閉包時一種常見的錯誤情況是循環中的閉包,很多初學者都遇到了這個問題。 閉包簡介 閉包是JavaScript的重要特性,那么什么是閉包? 《JavaScript高級程序設計(第3版)》中閉包的定義: 閉包就是指有權訪問另一個函數中的變...
摘要:注意由于閉包會額外的附帶函數的作用域內部匿名函數攜帶外部函數的作用域,因此,閉包會比其它函數多占用些內存空間,過度的使用可能會導致內存占用的增加。 作用域和作用域鏈是javascript中非常重要的特性,對于他們的理解直接關系到對于整個javascript體系的理解,而閉包又是對作用域的延伸,也是在實際開發中經常使用的一個特性,實際上,不僅僅是javascript,在很多語言中都...
摘要:也許最好的理解是閉包總是在進入某個函數的時候被創建,而局部變量是被加入到這個閉包中。在函數內部的函數的內部聲明函數是可以的可以獲得不止一個層級的閉包。 前言 總括 :這篇文章使用有效的javascript代碼向程序員們解釋了閉包,大牛和功能型程序員請自行忽略。 譯者 :文章寫在2006年,可直到翻譯的21小時之前作者還在完善這篇文章,在Stackoverflow的How do Java...
閱讀 3959·2021-10-19 13:23
閱讀 2337·2021-09-09 11:37
閱讀 2522·2019-08-29 15:20
閱讀 3416·2019-08-29 11:08
閱讀 1679·2019-08-26 18:27
閱讀 1774·2019-08-23 12:20
閱讀 3046·2019-08-23 11:54
閱讀 2564·2019-08-22 15:19