摘要:注意的值是一個匿名函數,而這個匿名函數本身也是一個閉包,所以相當于是一個,可以在函數外部對函數內部的局部變量進行操作。閉包會在父函數外部,改變父函數內部變量的值。
閉包(Closure)
關于閉包,真的是看了忘忘了看,相信這次應該理解了~
ES5中規定的JavaScript的變量作用域有兩種:全部變量和局部變量(ES6中引入塊級作用域)
javascript有兩種特殊的屬性
函數內部可以直接讀取全局變量
var n=999; function f1(){ alert(n); } f1(); // 999
函數外部不能夠讀取局部變量
function f1(){ var n=999; } alert(n); // error
注意 函數內部定義變量使用var,否則你定義的就是一個全局變量
function f1(){ n=999; } f1(); alert(n); // 999
上邊講到,正常情況下,外部無法讀取局部變量,想要讀取局部變量怎么辦?
就是在函數內部在定義一個函數
function f1(){ var n=999; function f2(){ alert(n); // 999 } }
在上面的代碼中,函數f2就被包括在函數f1內部,這時f1內部的所有局部變量,對f2都是可見的。但是反過來就不行,f2內部的局部變量,對f1就是不可見的。這就是Javascript語言特有的"鏈式作用域"結構(chain scope),子對象會一級一級地向上尋找所有父對象的變量。所以,父對象的所有變量,對子對象都是可見的,反之則不成立.
f2可以讀取f1中的變量,將f2作為返回值,那么f1的外部我們就可以讀取內部變量了
function f1(){ var n=999; function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999
上述代碼中f2就是閉包,下面看看抽象的閉包~
閉包:閉包是一個代碼塊(在ECMAScript是一個函數)和以靜態方式/詞法方式進行存儲的所有父作用域的一個集合體。所以,通過這些存儲的作用域,函數可以很容易的找到自由變量。
看看容易理解的閉包概念
由于在Javascript語言中,只有函數內部的子函數才能讀取局部變量,因此可以把閉包簡單理解成"定義在一個函數內部的函數"。
所以,在本質上,閉包就是將函數內部和函數外部連接起來的一座橋梁。
可以讀取函數內部的變量
就是讓這些變量的值始終保持在內存中
function f1(){ var n=999; nAdd=function(){n+=1} function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999 nAdd();#不要懷疑在外部為什么還可以調用,nAdd()是掛載在window下的 result(); // 1000
result其實就是閉包f2函數,一共運行兩次,一次999二次1000。這就說明f1局部變量一直在內存當中,
并沒有在被調用之后被自動的清楚。
為什么會這樣呢?原因就在于f1是f2的父函數,而f2被賦給了一個全局變量,這導致f2始終在內存中,而f2的存在依賴于f1,因此f1也始終在內存中,不會在調用結束后,被垃圾回收機制(garbage collection)回收。
注意nAdd的值是一個匿名函數(anonymous function),而這個匿名函數本身也是一個閉包,所以nAdd相當于是一個setter,可以在函數外部對函數內部的局部變量進行操作。
由于閉包會使得函數中的變量都被保存在內存中,內存消耗很大,所以不能濫用閉包,否則會造成網頁的性能問題,在IE中可能導致內存泄露。解決方法是,在退出函數之前,將不使用的局部變量全部刪除。
閉包會在父函數外部,改變父函數內部變量的值。所以,如果你把父函數當作對象(object)使用,把閉包當作它的公用方法(Public Method),把內部變量當作它的私有屬性(private value),這時一定要小心,不要隨便改變父函數內部變量的值。
題1
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ return function(){ return this.name; }; } }; alert(object.getNameFunc()());
題2
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ var that = this; return function(){ return that.name; }; } }; alert(object.getNameFunc()());參考資料
閉包
JavaScript核心
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/88050.html
摘要:當面試中讓我解釋一下閉包時我懵逼了。這個解釋開始可能有點晦澀,讓我們抽絲剝繭摘下閉包的真面目。此文不詳述作用域有專門的主題闡述,不過作用域是理解閉包原理的基礎。這才是閉包的真正便利之處。閉包使用不當就會很坑。 原文鏈接 為什么深度學習JavaScript? JavaScript如今是最流行的編程語言之一。它運行在瀏覽器、服務器、移動設備、桌面應用,也可能包括冰箱。無需我舉其他再多不相干...
摘要:哨兵是社區版本推出的原生高可用解決方案,部署架構主要包括兩部分集群和數據集群,其中集群是由若干節點組成的分布式集群。自研推薦推薦自研的高可用解決方案,主要體現在配置中心故障探測和的處理機制上,通常需要根據企業業務的實際線上環境來定制化。 最近很多朋友向我咨詢關于高可用的方案的優缺點以及如何選擇合適的方案線上使用,剛好最近在給宜人貸,光大銀行做企業內訓的時候也詳細講過,這里我再整理發出來...
摘要:哨兵是社區版本推出的原生高可用解決方案,部署架構主要包括兩部分集群和數據集群,其中集群是由若干節點組成的分布式集群。自研推薦推薦自研的高可用解決方案,主要體現在配置中心故障探測和的處理機制上,通常需要根據企業業務的實際線上環境來定制化。 最近很多朋友向我咨詢關于高可用的方案的優缺點以及如何選擇合適的方案線上使用,剛好最近在給宜人貸,光大銀行做企業內訓的時候也詳細講過,這里我再整理發出來...
閱讀 3267·2023-04-25 14:35
閱讀 3417·2021-11-15 18:00
閱讀 2537·2021-11-12 10:34
閱讀 2481·2021-11-11 16:54
閱讀 3464·2021-10-08 10:12
閱讀 2762·2021-09-06 15:02
閱讀 3318·2021-09-04 16:48
閱讀 2799·2019-08-29 14:02