JavaScript對內存的使用

內存的分配(示意)

啓動程序,就須要分配內存給運行的程序。啓動瀏覽器,就會分配必定內存供瀏覽器使用,瀏覽器在會分配相應的內存供諸如HTML+CSS,JS,'HTTP','其餘插件、定時器`等模塊使用,以下圖。
內存的分配面試

會有一部份內存供JS模塊使用,JS通常會將JS代碼存儲在代碼區,數據區內,經過某種聯繫將代碼和數據對應在一塊兒,以下圖。
內存的存儲瀏覽器

內存圖

示意圖

內存圖就是簡化模擬示意JS使用的內存中的數據區中的狀況,簡單的分爲棧內存Stack,堆內存Heap,以下圖。明顯,左邊是原始代碼,中間是棧內存,右邊是堆內存
內存圖spa

使用

左邊原始代碼定義一個變量,在棧內存中就會用64位存儲一個值。若是原始代碼中變量是非對象棧內存中這個值就是直接值堆內存沒有數據。若是原始代碼中變量是對象棧內存中就會存儲堆內存的地址(隨機),堆內存中會存儲這個對象的全部內容
內存圖使用_1_1插件

看到上個圖,原始代碼區裏最後一行O2=O,將一個對象賦值給另外一個變量時,其實是將堆內存的地址賦值給另外一個變量,轉換以下圖,O2在棧內存中的內容就變成了和O同樣的堆內存地址
內存圖使用_1_23d

應用實例

第一個

  • 原始代碼中定義變量a=1,Stack中存儲1
  • 原始代碼中定義變量b=a,Stack中存儲b的值和a同樣,爲1
  • 原始代碼中賦值b=2,都是非對象,Stack中直接將b的值改成2,不影響a
  • 全程非對象,因此沒有涉及堆內存Heap

數據類型面試題_1

第二個

  • 原始代碼中定義變量a={name:'a'},是個對象,隨機分配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地址

數據類型面試題_2

第三個

  • 原始代碼定義變量a={n:1},隨機分配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,如今a的值是ADDR 34,因此新屬性至關於x:ADDR 34。而後,把{n:2}賦值給a,由於是個新對象,因此從新分配Heap地址(ADDR 54),並把a的Stack值變動爲新的Heap地址(ADDR 51)。
  • alert(a.x),如今a的值實際是ADDR 54ADDR 54裏面是沒有x這個屬性的,因此返回undefined
  • alert(b.x),b一直是ADDR 34,其中x屬性值爲ADDR 54,因此是個對象,返回[object Object]
  • 總之就是,原始代碼裏對對象的操做都在堆內存Heap中實現,對變量的操做都在棧內存Stack中實現。非對象的Stack值就是直接值,對象的Stack值是堆內存Heap的地址

數據類型面試題_3

第四個

  • 原始代碼中定義變量a={name:'a'},Heap中存儲對象,Stack中存儲Heap地址(ADDR 101)
  • 原始代碼b=a,把a的Stack值(Heap地址)賦給b的Stack值
  • 原始代碼b={'name':'b'},賦給b一個新對象,Heap中存儲新對象,b的Stack值變動爲新的Heap地址(ADDR 301)
  • 因此,a.name沒有變,仍是a

數據類型面試題_4

第五個

  • 原始代碼中定義變量a={name:'a'},Heap中存儲對象,Stack中存儲Heap地址(ADDR 51)
  • 原始代碼b=a,把a的Stack值(Heap地址)賦給b的Stack值
  • 原始代碼設置b.name=b,就是ADDR 51中的name值變動爲b
  • 因此,a.name也就是ADDR 51中的name值,等於b
  • 這裏,a和b的Stack值都指向同一Heap地址ADDR 51,因此不管對那個進行操做,都是對一個東西作操做,因此會互相影響

數據類型面試題_5

相關文章
相關標籤/搜索