摘要:內(nèi)存圖示意圖內(nèi)存圖就是簡化模擬示意使用的內(nèi)存中的數(shù)據(jù)區(qū)中的情況,簡單的分為棧內(nèi)存堆內(nèi)存,如下圖。明顯,左邊是原始代碼,中間是棧內(nèi)存,右邊是堆內(nèi)存。如果原始代碼中變量是對象,棧內(nèi)存中就會存儲堆內(nèi)存的地址隨機(jī),堆內(nèi)存中會存儲這個對象的所有內(nèi)容。
內(nèi)存的分配(示意)
啟動程序,就需要分配內(nèi)存給運(yùn)行的程序。啟動瀏覽器,就會分配一定內(nèi)存供瀏覽器使用,瀏覽器在會分配相應(yīng)的內(nèi)存供諸如HTML+CSS,JS,"HTTP","其他插件、定時器`等模塊使用,如下圖。
會有一部分內(nèi)存供JS模塊使用,JS一般會將JS代碼存儲在代碼區(qū),數(shù)據(jù)區(qū)內(nèi),通過某種聯(lián)系將代碼和數(shù)據(jù)對應(yīng)在一起,如下圖。
內(nèi)存圖就是簡化模擬示意JS使用的內(nèi)存中的數(shù)據(jù)區(qū)中的情況,簡單的分為棧內(nèi)存Stack,堆內(nèi)存Heap,如下圖。明顯,左邊是原始代碼,中間是棧內(nèi)存,右邊是堆內(nèi)存。
左邊原始代碼定義一個變量,在棧內(nèi)存中就會用64位存儲一個值。如果原始代碼中變量是非對象,棧內(nèi)存中這個值就是直接值,堆內(nèi)存中沒有數(shù)據(jù)。如果原始代碼中變量是對象,棧內(nèi)存中就會存儲堆內(nèi)存的地址(隨機(jī)),堆內(nèi)存中會存儲這個對象的所有內(nèi)容。
看到上個圖,原始代碼區(qū)里最后一行O2=O,將一個對象賦值給另一個變量時,實際上是將堆內(nèi)存的地址賦值給另一個變量,轉(zhuǎn)換如下圖,O2在棧內(nèi)存中的內(nèi)容就變成了和O一樣的堆內(nèi)存地址。
原始代碼中定義變量a=1,Stack中存儲1
原始代碼中定義變量b=a,Stack中存儲b的值和a一樣,為1
原始代碼中賦值b=2,都是非對象,Stack中直接將b的值改為2,不影響a
全程非對象,所以沒有涉及堆內(nèi)存Heap
第二個原始代碼中定義變量a={name:"a"},是個對象,隨機(jī)分配Heap地址(比如:31)并在Heap中存儲這個對象,在Stack中存儲這個Heap地址,比如ADDR 31
原始代碼中定義變量b=a,是個存在的對象,將a的Stack值(ADDR 31)(Heap地址)賦給b的Stack值
原始代碼中賦值b=null,賦給了b一個非對象,將b的Stack值改為null,不影響a
全程操作Stack值,對象的Stack值為Heap地址
第三個原始代碼定義變量a={n:1},隨機(jī)分配Heap地址(比如:34)并在Heap中存儲這個對象,在Stack中存儲這個Heap地址,比如ADDR 34
原始代碼中定義變量b=a,是個存在的對象,將a的Stack值(ADDR 34)(Heap地址)賦給b的Stack值
a.x=a={n:2},這句話閱讀順序從左往右。首先,在Heap 34中添加新屬性x:a,現(xiàn)在a的值是ADDR 34,所以新屬性相當(dāng)于x:ADDR 34。然后,把{n:2}賦值給a,因為是個新對象,所以重新分配Heap地址(ADDR 54),并把a(bǔ)的Stack值變更為新的Heap地址(ADDR 51)。
alert(a.x),現(xiàn)在a的值實際是ADDR 54,ADDR 54里面是沒有x這個屬性的,所以返回undefined
alert(b.x),b一直是ADDR 34,其中x屬性值為ADDR 54,所以是個對象,返回[object Object]
總之就是,原始代碼里對對象的操作都在堆內(nèi)存Heap中實現(xiàn),對變量的操作都在棧內(nèi)存Stack中實現(xiàn)。非對象的Stack值就是直接值,對象的Stack值是堆內(nèi)存Heap的地址
第四個原始代碼中定義變量a={name:"a"},Heap中存儲對象,Stack中存儲Heap地址(ADDR 101)
原始代碼b=a,把a(bǔ)的Stack值(Heap地址)賦給b的Stack值
原始代碼b={"name":"b"},賦給b一個新對象,Heap中存儲新對象,b的Stack值變更為新的Heap地址(ADDR 301)
所以,a.name沒有變,還是a
第五個原始代碼中定義變量a={name:"a"},Heap中存儲對象,Stack中存儲Heap地址(ADDR 51)
原始代碼b=a,把a(bǔ)的Stack值(Heap地址)賦給b的Stack值
原始代碼設(shè)置b.name=b,就是ADDR 51中的name值變更為b
所以,a.name也就是ADDR 51中的name值,等于b
這里,a和b的Stack值都指向同一Heap地址,ADDR 51,所以無論對那個進(jìn)行操作,都是對一個東西做操作,所以會互相影響
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/107972.html
摘要:在試圖弄清這個問題之前,先要理解棧內(nèi)存堆內(nèi)存和預(yù)處理。因此在子函數(shù)執(zhí)行的時候,堆內(nèi)存被占用了,相應(yīng)的棧內(nèi)存也將保留。所以,棧內(nèi)存在執(zhí)行完之后會被保留一段時間,這段時間等于其子函數(shù)執(zhí)行的時間。 在試圖弄清這個問題之前,先要理解棧內(nèi)存、堆內(nèi)存和預(yù)處理。 占用內(nèi)存,不會銷毀的閉包實例 例1: var num = 12; function fn() { var num = 100; ...
摘要:中對內(nèi)存的一些了解在進(jìn)行開發(fā)的過程中了解內(nèi)存機(jī)制有助于開發(fā)人員能夠清晰的認(rèn)識到自己寫的代碼在執(zhí)行的過程中發(fā)生過什么也能夠提高項目的代碼質(zhì)量內(nèi)存是怎么樣的中變量存放有著原始值與引用值之分原始值原始的數(shù)據(jù)類型以及新加入的引用值等類型的值便是引用 JS中對內(nèi)存的一些了解 在JS進(jìn)行開發(fā)的過程中, 了解JS內(nèi)存機(jī)制有助于開發(fā)人員能夠清晰的認(rèn)識到自己寫的代碼在執(zhí)行的過程中發(fā)生過什么, 也能夠提高...
摘要:事件對內(nèi)存和性能的影響雖說事件處理程序可以為現(xiàn)代頁面添加很強(qiáng)的交互能力,但是不分青紅皂白就添加大量的事件處理程序絕對是一種愚蠢的行為。最適合采用事件委托的事件包括和。提交提交某個表單的操作代碼移除事件處理程序提交中。。。 JavaScript 事件對內(nèi)存和性能的影響 雖說事件處理程序可以為現(xiàn)代 Web 頁面添加很強(qiáng)的交互能力,但是不分青紅皂白就添加大量的事件處理程序絕對是一種愚蠢的行為...
摘要:解釋器的利弊解釋器啟動和執(zhí)行的更快。正是因為這個原因,解釋器看起來更加適合。這就是為什么最開始的瀏覽器都是用解釋器的原因。可是當(dāng)你運(yùn)行同樣的代碼一次以上的時候,解釋器的弊處就顯現(xiàn)出來了。起初,監(jiān)視器監(jiān)視著所有通過解釋器的代碼。 作者:Lin Clark 編譯:胡子大哈 翻譯原文:http://huziketang.com/blog/posts/detail?postId=58c12f...
閱讀 3152·2021-09-30 09:47
閱讀 2003·2021-09-22 16:04
閱讀 2274·2021-09-22 15:44
閱讀 2534·2021-08-25 09:38
閱讀 540·2019-08-26 13:23
閱讀 1221·2019-08-26 12:20
閱讀 2808·2019-08-26 11:59
閱讀 1077·2019-08-23 18:40