js的陣列/物件在記憶體中分別是如何儲存的?

王铁柱6發表於2024-12-04

JavaScript中的陣列和物件在記憶體中的儲存方式不同,它們分別使用了不同的資料結構:

陣列 (Array):

JavaScript的陣列實際上是特殊的物件,但為了最佳化效能,引擎通常會使用連續的記憶體塊來儲存陣列元素。這意味著陣列元素在記憶體中是線性排列的,可以透過索引快速訪問。

  • 連續記憶體: 陣列元素通常儲存在連續的記憶體塊中,每個元素佔據相同大小的記憶體空間。這使得透過索引訪問元素非常高效,因為可以透過簡單的地址計算直接找到元素的位置。
  • 元素型別: 儘管JavaScript陣列可以儲存不同型別的資料,但為了最佳化,引擎通常會嘗試儲存相同型別的元素。如果陣列中儲存了不同型別的資料,引擎可能會採用一些策略來處理這種異構性,但這可能會影響效能。
  • 動態擴容: 當陣列需要儲存更多元素時,如果當前的記憶體塊已滿,引擎會分配一個更大的記憶體塊,並將現有元素複製到新的記憶體塊中。這個過程稱為動態擴容,可能會導致效能開銷。
  • 稀疏陣列: 如果陣列的索引不連續(例如,arr[100] = 'hello',而其他索引未賦值),引擎可能會使用不同的儲存策略,例如雜湊表或連結串列,以避免浪費大量的記憶體空間。在這種情況下,訪問元素的效能可能會低於密集陣列。

物件 (Object):

JavaScript的物件使用雜湊表(或類似的結構)來儲存鍵值對。

  • 雜湊表: 物件中的每個屬性名(鍵)都會被雜湊成一個數值,這個數值用於在雜湊表中查詢對應的值。
  • 鍵值對: 雜湊表儲存的是鍵值對,其中鍵是字串(即使你使用數字作為鍵,它也會被轉換為字串),值可以是任何JavaScript資料型別。
  • 屬性訪問: 當你訪問物件的屬性時,引擎會先將屬性名雜湊,然後在雜湊表中查詢對應的值。這個過程比陣列的索引訪問略慢,但仍然非常高效。
  • 屬性順序: 在ES2015之前,JavaScript物件屬性的順序沒有明確的規範。ES2015之後,物件屬性的順序得到了一定的保證,但仍然有一些特殊情況需要注意。 一般來說,插入順序會保留,但數字鍵會先被排序,然後才是字串鍵按插入順序排列。

總結:

特性 陣列 物件
資料結構 通常是連續記憶體塊 (或針對稀疏陣列的特殊結構) 雜湊表
元素訪問 透過索引,非常快速 透過鍵,快速,但比陣列索引略慢
數字索引 字串鍵 (即使是數字也會被轉換為字串)
順序 元素順序固定 屬性順序在ES2015後得到一定保證,但仍有特殊情況
記憶體分配 連續記憶體塊,動態擴容 根據需要動態分配

理解JavaScript陣列和物件在記憶體中的儲存方式,有助於你編寫更高效的程式碼。例如,如果你需要頻繁訪問元素,使用陣列通常比物件更高效。而如果你需要儲存鍵值對,並且鍵不是數字,那麼物件是更好的選擇。

相關文章