Does Spreading create shallow copy?
Asked Answered
P

3

0

As per the example given here,

let first:number[] = [1, 2];
let second:number[] = [3, 4];

let both_plus:number[] = [0, ...first, ...second, 5];
console.log(`both_plus is ${both_plus}`);
first[0] = 20;
console.log(`first is ${first}`);
console.log(`both_plus is ${both_plus}`);
both_plus[1]=30;
console.log(`first is ${first}`);
console.log(`both_plus is ${both_plus}`);

Spreading shows a deep copy, because all three array's have it's own duplicates, based on below output:

both_plus is 0,1,2,3,4,5
first is 20,2
both_plus is 0,1,2,3,4,5
first is 20,2
both_plus is 0,30,2,3,4,5

Documentation says: Spreading creates a shallow copy of first and second. How do I understand this?

Predict answered 26/4, 2018 at 20:13 Comment(2)
It's the same as [0, 1, 2, 3, 4, 5]. You can't really tell if a copy is deep if all you've got are primitives.Jewfish
No, spread syntax doesn't create or copy anything. It's the array literal that creates the new array.Edmanda
F
16

In your case a shallow copy and deep copy are the same. For an array containing only primitives, they will always be identical. You'll only notice the difference when your array contains other objects.

Javascript is pass by value, so when an array is shallow copied (such as by using spread), each value in the original array is copied to the new array. In the case of a primitive, the value is copied directly and changes made to it have no effect on the original.

However, when the array contains objects, each value is itself a reference to something else. So even though the reference has been copied to a new array, it still points to the same thing as the reference in the original array. So while mutating the new array will not change the original, mutating the elements of the array will affect the original.

Here's an example:

const objArray = [{foo: "bar"}];
const shallowCopy = [...objArray];

// Changing the array itself does not change the orignal. Note the
// original still only has one item, but the copy has two:
shallowCopy.push({foo: "baz"});
console.log("objArray after push:", objArray);
console.log("shallowCopy after push:", shallowCopy);

// However, since shallowCopy[0] is a reference pointing to the same object
// as objArray[0], mutating either will change the other:
shallowCopy[0].foo = "something else";
console.log("objArray after mutation:", objArray);
console.log("shallowCopy after mutation:", shallowCopy);
Feint answered 26/4, 2018 at 20:39 Comment(0)
J
3

Shallow copy means that all of the elements from first and second are merely added to the new array, the new copy. Deep copy would mean that all of the elements from first and second are first copied then added to the new array.

The distinction being whether the elements themselves are copied into a new object before being added to the new array.

Using primitives, like numbers, it is not really possible to illustrate the difference, but if you use objects the difference is pretty clear.

Say you have something like this:

let first = [{foo: 'bar'}];
let second = [{fizz: 'buzz'}];
let both = [...first, ...second];

Since spreading results in a shallow copy you can expect the relevant objects to pass an equality test:

first[0] === both[0]; // true
second[0] === both[1]; // true

But if spreading resulted in a deep copy you would expect the equality test to fail:

first[0] === both[0]; // false
second[0] === both[1]; // false
Jemie answered 26/4, 2018 at 20:38 Comment(1)
On my machine, the results evaluated to first[0] === both[0]; // false, second[0] === both[1]; // trueDevotion
A
3

Spreading results in a shallow copy

const a = [{x: 1}, {y: 1}];
const b = a;

const c = [...a, ...b];
console.log(c); // [{x: 1}, {y: 1}, {x: 1}, {y: 1}]

a[1]['y'] = 5;
console.log(c); // [{x: 1}, {y: 5}, {x: 1}, {y: 5}]
Adi answered 14/6, 2020 at 13:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.