摘要:我的理解就是還處于被引用狀態(tài)。內(nèi)存機制的內(nèi)存空間分為棧堆其中棧存放變量,堆存放復(fù)雜對象。對堆內(nèi)數(shù)據(jù)進行復(fù)制修改時理解閉包有了前面的鋪墊,我們再來看看閉包是怎么回事。這種反常的現(xiàn)象我們就叫它,中文名閉包。這就是閉包形成的原因了。
知識小儲備
ECMAScript 的數(shù)據(jù)有兩種類型:基本類型值和引用類型值,基本類型指的是簡單的數(shù)據(jù)段,引用類型指的是可能由多個值構(gòu)成的對象。垃圾回收Undefined、Null、Boolean、Number 和 String 是值類型,其他都是引用類型。
我們創(chuàng)建的原始類型、對象、函數(shù)等等,都會占用內(nèi)存。為了防止溢出,我們就需要對不用的數(shù)據(jù)進行刪除。這就是垃圾回收。
可觸及(Reachability)JavaScript 內(nèi)存管理的關(guān)鍵概念是可觸及(Reachability)。
我的理解就是還處于被引用狀態(tài)。
將全局(無論是window還是global)比作樹根,我們創(chuàng)建的原始類型、對象、函數(shù)等等比作一個個枝杈。如果可以從window不斷層的知道某個變量,那這個變量就是可觸及的,不可回收的。
舉個例子:
// user has a reference to the object let user = { name: "John" };
箭頭代表的是對象引用。全局變量 "user" 引用了對象{name: "John"}(簡稱此對象為 John)。John 的 "name" 屬性儲存的是一個原始值,所以無其他引用。
如果覆蓋 user,對 John 的引用就丟失了:
user = null;
現(xiàn)在 John 變得不可觸及,垃圾回收機制會將其刪除并釋放內(nèi)存。
內(nèi)存機制js的內(nèi)存空間分為棧 (stack)、堆 (heap);其中棧存放變量,堆存放復(fù)雜對象。
借用一張圖直觀感受一下
只能存放基本數(shù)據(jù)類型的數(shù)據(jù)和對象類型的引用地址也叫哈希碼。里面的數(shù)據(jù)后進先出。
對棧內(nèi)數(shù)據(jù)進行復(fù)制修改時:
是用來存儲 “數(shù)組類型” 和“對象類”的數(shù)據(jù)。特點是存儲空間大。
對堆內(nèi)數(shù)據(jù)進行復(fù)制修改時:
有了前面的鋪墊,我們再來看看閉包是怎么回事。還是舉個例子:
//決策層開會決定生產(chǎn)新一代phone手機,就弄了個叫PhoneFactory的企劃案 let Proposal = function(){ //新一代手機信息被封裝在企劃案中 let version = "XX", money = 10000 return function (){ //生產(chǎn)新的手機 return { version: version, money: money } } } //執(zhí)行者根據(jù)策劃案建成了一個工廠, 工廠方法每執(zhí)行一次就產(chǎn)出一個手機 let Factory = new Proposal(); let phone1 = Factory(); console.log(phone1.version)
對于手機的version, money而言, 它是策劃書Proposal的內(nèi)部變量,而Proposal的同級phone1應(yīng)該是訪問不到。但實際上我們還是拿到了手機的版本和價格數(shù)據(jù)。這種反常的現(xiàn)象我們就叫它Closure,中文名閉包。
原因我們不管它為什么叫這個名字,先看看具體是什么原因產(chǎn)生的。
根據(jù)上面說的垃圾回收機制。函數(shù)Proposal在執(zhí)行過之后(第16行)就沒有引用。那么Proposal久應(yīng)該被回收。里面的所有內(nèi)部變量也應(yīng)該被回收了。
但實際上 Proposal返回了一個新的函數(shù)Factory。而這個Factory是要能夠訪問到它生成時的同級以及父祖輩變量。而Proposal內(nèi)部變量version, money就有了新的引用。因而阻止了被回收。就像Factory生成了一個新的泡泡把它能訪問到的作用域包裹了起來。這就是閉包形成的原因了。
基于上面的js內(nèi)存機制的知識,我們可以畫出下面這張圖:
圖簡陋了點。。。。
但也可以看出,對于變量version,money而言。雖然他們本身在proposal的黃色作用域中。但也在fatory生成的時候也被包含在了fatory打的可訪問的作用域氣泡內(nèi)。不僅他們,甚至更外層的也都被包含在內(nèi)。
在proposal這個泡泡破碎之后,只有當(dāng)打的紅色泡泡也破了,這些變量才會真的被回收。這也是為什么閉包用多了會影響性能的原因。
前端基礎(chǔ)進階:詳細(xì)圖解 JavaScript 內(nèi)存空間
垃圾回收
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/96310.html
摘要:如何在初學(xué)就理解閉包你需要接著讀下去。這樣定義閉包是函數(shù)和聲明該函數(shù)的詞法環(huán)境的組合。小結(jié)閉包在中隨處可見。閉包是中的精華部分,理解它需要具備一定的作用域執(zhí)行棧的知識。 這是本系列的第 4 篇文章。 作為 JS 初學(xué)者,第一次接觸閉包的概念是因為寫出了類似下面的代碼: for (var i = 0; i < helpText.length; i++) { var item = he...
摘要:當(dāng)初看這個解釋有點懵逼,理解成閉包就是函數(shù)中的函數(shù)了。里的閉包最近不滿足于只干前端的活,開始用起了。里的閉包最近在學(xué)習(xí)語言,讓我們來看一下語言里的閉包。在中,閉包特指將函數(shù)作為值返回的情況,被返回的函數(shù)引用了生成它的母函數(shù)中的變量。 本人開始接觸編程是從js開始的,當(dāng)時網(wǎng)上很多人說閉包是難點,各種地方對閉包的解釋也是千奇百怪。如今開始接觸js以外的各種編程語言,發(fā)現(xiàn)不光是js,php、...
摘要:當(dāng)初看這個解釋有點懵逼,理解成閉包就是函數(shù)中的函數(shù)了。里的閉包最近不滿足于只干前端的活,開始用起了。里的閉包最近在學(xué)習(xí)語言,讓我們來看一下語言里的閉包。在中,閉包特指將函數(shù)作為值返回的情況,被返回的函數(shù)引用了生成它的母函數(shù)中的變量。 本人開始接觸編程是從js開始的,當(dāng)時網(wǎng)上很多人說閉包是難點,各種地方對閉包的解釋也是千奇百怪。如今開始接觸js以外的各種編程語言,發(fā)現(xiàn)不光是js,php、...
摘要:閉包在我理解是一種比較抽象的東西。所以我寫了一篇博文來方便自己理解閉包。那么現(xiàn)在我們可以解釋一下閉包的第一個定義在計算機科學(xué)中,閉包是引用了自由變量的函數(shù)。循環(huán)中創(chuàng)建閉包在我們使用的關(guān)鍵字之前,閉包的一個常見問題就出現(xiàn)在循環(huán)中創(chuàng)建閉包。 零. 前言 從我開始接觸前端時就聽說過閉包,但是一直不理解閉包究竟是什么。上網(wǎng)看了各種博客,大家對閉包的說法不一。閉包在我理解是一種比較抽象的東西。所...
摘要:但是閉包也不是什么復(fù)雜到不可理解的東西,簡而言之,閉包就是閉包就是函數(shù)的局部變量集合,只是這些局部變量在函數(shù)返回后會繼續(xù)存在。可惜的是,并沒有提供相關(guān)的成員和方法來訪問閉包中的局部變量。 (收藏自 技術(shù)狂) 前言:還是一篇入門文章。Javascript中有幾個非常重要的語言特性——對象、原型繼承、閉包。其中閉包 對于那些使用傳統(tǒng)靜態(tài)語言C/C++的程序員來說是一個新的語言特性。本文將...
閱讀 3768·2021-08-30 09:47
閱讀 3690·2019-08-30 15:56
閱讀 677·2019-08-30 14:18
閱讀 698·2019-08-29 16:17
閱讀 2065·2019-08-29 11:07
閱讀 642·2019-08-26 13:53
閱讀 3443·2019-08-26 10:26
閱讀 2491·2019-08-23 18:30