Shallow Clone vs Deep Clone in JavaScript
In JavaScript programming, we would encounter many scenarios copying data to a new variable, i.e. data cloning. Because of the existence of reference data, we should definitely think about when to use shallow clone as well as deep clone. We are gonna talk about what are they, how do they work and implementation of them from scratch.
Shallow Clone
A shallow clone means that only the top-level properties of the original object are copied, and any nested objects or arrays are still shared by the original and the copy.
So if the property is a primitive, then the value would be copied as a new one; If it is a reference type (Object, Array, etc), then only address would be copied, modifying which would change the value of the new data.
Let’s introduce some methods to do shallow clone.
Method 1: object.assign
object.assign is an ES6 method in object. It merges the second and the trailing objects into the first object.
1 | let target = {}; |
Since it’s a shallow clone, then modifying the b value of source, which is inside object a, would affect the target object as well:
1 | let target = {}; |
Tips: using object.assign
- CAN NOT copy inheritence properties
- CAN NOT copy non-enumerable properties
- CAN copy Symbol properties
Method 2: Spread Operator
1 | /* copy object */ |
Method 3: Array Concat
Only for array’s shallow clone:
1 | let arr = [1, 2, 3]; |
Method: Array Slice
Only for array’s shallow clone:
1 | let arr = [1, 2, {val: 4}]; |
Try Implement a Shallow Clone
There are two ideas for implementing a shallow clone function:
- For primitives, just copy it
- For reference data, allocate a new space, and then copy the first level of its properties.
1 | function shallowClone(target) { |
Deep Clone
Instead of just copying the first level of properties, a deep clone copies data in depth, which completely separate the storage of the data in memory.
There are also a few methods to achieve deep clone.
Method 1: JSON.stringify + JSON.parse
This is the simplest way to do deep clone in practice. It converts an object to a JSON string, which we can use JSON.parse to recover it as a brand new object.
1 | let obj1 = { a:1, b:[1,2,3] } |
However, there are some limitations of this method after a conversion:
- CAN NOT copy:
function,undefined,symbol - CAN NOT copy non-enumerable properties
- CAN NOT copy prototype chain
- CAN NOT copy circular references, i.e.
obj[key] = obj Datevalue would becomestringRegExpvalue would become{}NaN,+-Infinityvalue would becomenull
Here is a code example:
1 | function Obj() { |

Method 2: Basic Recursion Implementation
Use for..in loop to iterate properties:
- if it is a reference type, recursively call the clone
- else, copy it
1 | function deepClone(target) { |
For this basic version, we still cannot deal with:
- Non-enumerable and symbol properties
- Array, Date, RegExp, Error, Function properties
- Circular reference properties
Method 3: Advanced Implementation
Regarding the above shortages, we can solve them in these ways:
- For non-enumerable and symbol properties, we can use
Reflect.ownKeysto iterator them - For
Date,RegExpproperties, we create new instances based on them - For prototype chain, we can use
Object.getOwnPropertyDescriptorsto get every property, attribute on the object; Along withObject.createto create a new object, we can pass the prototype chain of the original object to inherit it. - For circular references, using
WeakMapas hash table can detect them as well as avoiding memory leak.
WeakMap is a special kind of Map whose keys must be objects, and it does not prevent its keys from being garbage.
Now let’s take a look at the advanced version:
1 | function deepClone(obj, map = new WeakMap()) { |
Test this complex function:
1 | let obj = { |

The resule shows we have done deep clone perfectly🔥
Summary
Getting familiar with shallow clone and deep clone is crucial for javascript programming. By implementing them, there are many knowledge have been tested:
- Basic coding skills
- Recursion
- Preciseness
- Abstraction
- JS coding skills
- Type checking
- APIs of reference types
- WeakMap
- Comprehensive skills
- Edge cases
- Circular reference detection
See, we’ve come so far!
That’s all for today’s topic. Hope these clone stuffs become clear to you!