Deep copy object and array using spread operator
Table of contents
What is swallow copy vs deep copy?
A deep copy means that all of the values of the new variable are copied and disconnected from the original variable.
A shallow copy means that certain (sub-)values are still connected to the original variable.
When swallow copy is created?
To really understand copying, you have to get into how JavaScript stores values.
Primitive data types:
- Number — e.g. 1
- String — e.g. 'Hello'
- Boolean — e.g. true
- undefined
- null
When you create these values, they are tightly coupled with the variable they are assigned to. They only exist once.
That means you do not really have to worry about copying primitive data types in JavaScript. When you make a copy, it will be a real copy.
let a = 5let b = a // this is the copyb = 6console.log(b) // 6console.log(a) // 5
Composite data types:
- Object
- Array
Technically, arrays are also objects, so they behave in the same way. These values are actually stored just once when instantiated, and assigning a variable just creates a pointer (reference)
to that value.
Now, if we make a copy b = a
, and change some nested value in b
, it actually changes a
’s nested value as well 🤯
Why? Because a
and b
actually point to the same reference
. It's called swallow copy.
let a = { name: 'Pollob' }let b = aconsole.log(b) // { name: 'Pollob' }b.name = "Something .."console.log(a) // { name: 'Something ..' }
Deep copy to rescue
Deep copy object
// badconst old = { a: 1, b: 2 };const copy = Object.assign({}, old); // copy => { a: 1, b: 2 }// adding additional valueconst copy = Object.assign({}, old, { c: 3 }); // copy => { a: 1, b: 2, c: 3 }// goodconst old = { a: 1, b: 2 };const copy = { ...old }; // copy => { a: 1, b: 2 }// adding additional valueconst copy = { ...old, c: 3 }; // copy => { a: 1, b: 2, c: 3 }const { a, ...args } = copy; // args => { b: 2, c: 3 }
Deep copy array
// badconst items = [1,2,3,4,5]const len = items.length;let itemsCopy = [];let i;for (i = 0; i < len; i += 1) {itemsCopy[i] = items[i];}// baditemsCopy = items.slice();// baditemsCopy = new Array(items)// goodconst itemsCopy = [...items];