For as long as anyone can remember, deep copying in JavaScript was not a built-in feature and we had to resort to libraries or workarounds to create a deep copy of a JavaScript value.
That has changed now.
The platform now offers a built-in function that does deep copying for us: structuredClone()
Before getting into deep copying, let us discuss what shallow copy is. The default behavior of copying in JavaScript is to shallow copy. That means that whenever we create a copy of something, changes to nested values in the original value will be reflected in the copied object as well.
let ingredients_list = ["noodles",{"list":["eggs","flour","water"]}];
let ingredients_list_copy = Array.from(ingredients_list);
ingredients_list_copy[1].list = ["rice flour","water"]
console.log(ingredients_list[1].list);
JavaScriptEven if we use the spread operator, it only goes one level deep. Deeply nested properties are still shallow copied.
const arr = [1, 2, 3];
const arr2 = [...arr]; // like arr.slice()
arr2.push(4);
// arr2 becomes [1, 2, 3, 4]
// arr remains unaffected because it is not deeply nested
const oldObj = {a: {b: 10}, c: 2};
const newObj = {...oldObj};
oldObj.a.b = 2;
console.log(newObj.a.b);
// 2
// newObj `b` value gets updated as it is allocated at the same address
JavaScriptThis happens because non-primitive types in JavaScript are handled as references by default. The act of copying them is merely the act of copying the reference to the underlying object. They get allocated the same memory address under the hood. This results in a shallow copy every time a non-primitive object is copied.
Deep copying is the opposite of shallow copying. All the nested properties are copied on an individual basis and whenever a nested property is found, the copying happens recursively, creating an actual copy of that property as well. This results in the copied object not sharing anything with the original object.
Until now, people either relied on Lodash’s cloneDeep() method to achieve deep copying, or the most common hack was:
const myDeepCopy = JSON.parse(JSON.stringify(myOriginal));
JavaScriptIn fact, its popularity made the V8 engine optimize JSON.parse for making the above statement execute faster.
While it works amazingly well, there are a couple of shortcomings of that method:
The HTML spec was updated to expose a function called structuredClone() that creates deep copies of JavaScript values. The entire API is a single line:
const myDeepCopy = structuredClone(myOriginal);
JavaScriptAnd it does exactly what you would assume it to do!
There are a couple of limitations, though:
But considering that it is a part of the HTML spec now, I guess we can rely on using structuredClone for deep copying in JavaScript until we run into one of the above limitations for some special use cases.
We no longer need to reach out to other libraries or our good old friend JSON.parse for deep copying in JavaScript!
I recently switched completely to the Brave browser and have set ad blocking to aggressive…
I was preparing a slide deck for a hackathon and decided to put in a…
I have been using npx a lot lately, especially whenever I want to use a…
Manually copy-pasting the output of a terminal command with a mouse/trackpad feels tedious. It is…
While working on a project, I wanted to do an integrity check of a file…
Popovers have been a problem that was typically solved by using a third-party solution. But…