Javascript Array.concat (Shallow copy)

starzodiac
Dec 8, 2020

--

之前看 MDN 提到一段話:

concat 方法不會改變 this 自己本身或是任何被提供當做參數的陣列,取而代之則是回傳一個淺層複製(shallow copy)包含了與原始的陣列中一樣的元素的副本。原始陣列的元素被複製到新的陣列的規則如下所示:

物件參考(並非為實際的物件):concat 複製物件的參考至新的陣列。不管是原始的還是新的陣列都參考到相同的物件。也就是說,如果一個被參照的物件被修改了,變動會同時反映到新的以及原始的陣列中。

資料型態為字串、數值或是布林(非 StringNumberBoolean 物件):concat 複製字串及數值的值到新的陣列。

後來自己試了一下,想說怎麼跟我想像中的 shallow copy 不一樣:

var arr4 = [1, 2, 3];
var arr5 = arr4.concat([]);
if (arr4 === arr5)
console.log("arr4 is clone of arr5");
else
console.log("arr4 is not clone of arr5");
output:
arr4 is not clone of arr5

後來才發現重點是:

物件參考(並非為實際的物件):concat 複製物件的參考至新的陣列。不管是原始的還是新的陣列都參考到相同的物件。也就是說,如果一個被參照的物件被修改了,變動會同時反映到新的以及原始的陣列中。

所以只有當 concat 的對象是物件 (object) 時,JS 才會做 shallow copy~

(其實 MDN 上的例子很清楚了XD)

另外,我在這個網站看到了一些整理,把重點貼出來:

「call by reference」與「call by value」?

  • 基本型別 (Primitive Type) — number, string, boolean, null, undefined — 傳值
  • 物件 (Objects) — array, function, object — 傳址
  • array/object 當中若含有複合型別時,此複合型別是 call by reference 而不是 by value。

「淺拷貝」與「深拷貝」的定義與差異?

  • 淺拷貝在複製 object 時,會參考到同一個物件,並沒有將此物件拷貝到並建立出新的關聯。(call by reference)
  • 深拷貝在複製 object 時,會獨立出來不共用同一個記憶體位置,改動 newObject 時不會動到 oldObject。(call by value)

--

--

No responses yet