Use JSON for deep copy

var newObject = JSON.parse(JSON.stringify(oldObject))

var oldObject = {
  name: 'A',
  address: {
    street: 'Station Road',
    city: 'Pune'
  }
}
var newObject = JSON.parse(JSON.stringify(oldObject));

newObject.address.city = 'Delhi';
console.log('newObject');
console.log(newObject);
console.log('oldObject');
console.log(oldObject);
Run code snippetEdit code snippet Hide Results Copy to answer Expand

Answer from Nikhil Mahirrao on Stack Overflow
Top answer
1 of 15
173

Use JSON for deep copy

var newObject = JSON.parse(JSON.stringify(oldObject))

var oldObject = {
  name: 'A',
  address: {
    street: 'Station Road',
    city: 'Pune'
  }
}
var newObject = JSON.parse(JSON.stringify(oldObject));

newObject.address.city = 'Delhi';
console.log('newObject');
console.log(newObject);
console.log('oldObject');
console.log(oldObject);
Run code snippetEdit code snippet Hide Results Copy to answer Expand

2 of 15
90

No such functionality is built-in to ES6. I think you have a couple of options depending on what you want to do.

If you really want to deep copy:

  1. Use a library. For example, lodash has a cloneDeep method.
  2. Implement your own cloning function.

Alternative Solution To Your Specific Problem (No Deep Copy)

However, I think, if you're willing to change a couple things, you can save yourself some work. I'm assuming you control all call sites to your function.

  1. Specify that all callbacks passed to mapCopy must return new objects instead of mutating the existing object. For example:

    mapCopy(state, e => {
      if (e.id === action.id) {
        return Object.assign({}, e, {
          title: 'new item'
        });
      } else {  
        return e;
      }
    });
    

    This makes use of Object.assign to create a new object, sets properties of e on that new object, then sets a new title on that new object. This means you never mutate existing objects and only create new ones when necessary.

  2. mapCopy can be really simple now:

    export const mapCopy = (object, callback) => {
      return Object.keys(object).reduce(function (output, key) {
        output[key] = callback.call(this, object[key]);
        return output;
      }, {});
    }
    

Essentially, mapCopy is trusting its callers to do the right thing. This is why I said this assumes you control all call sites.

🌐
Medium
medium.com › @akshayvgupta7 › spread-operator-vs-shallow-copy-vs-deep-copy-fab5302c5a4a
Spread Operator vs Shallow Copy vs Deep Copy | by Akshay Gupta | Medium
June 28, 2024 - Here, JSON.stringify(obj1) converts the obj1 array into a JSON string and, JSON.parse(...) then parses this string back into a new object, creating a deep copy. Note: The same concept will work for arrays as well. ... const arr = [[1], 2, 3, 4]; const b = arr; // b is assigned the reference to the same array as arr. // shallow copy using spread operator const c = [...arr]; // pushing in nested array, which has the same reference as arr[0] has c[0].push(2); // here we are not pushing in nested array, so it will not impact b or arr c.push(5); console.log("c : ", c); // Output: [ [ 1, 2 ], 2, 3, 4, 5 ] console.log("b : ", b); // Output: [ [ 1, 2 ], 2, 3, 4 ] console.log("arr: ", arr);// Output: [ [ 1, 2 ], 2, 3, 4 ]
Discussions

javascript - Object copy using spread syntax actually shallow or deep? - Stack Overflow
I noticed this statement "it deep copies the data if it is not nested" all over the internet, but it's nonsense. Spread operator does a simple shallow copy, period. The problem is that people probably don't understand the difference between a primitive value and a reference to an object in C-like languages like C++, C#, Java and JavaScript... More on stackoverflow.com
🌐 stackoverflow.com
javascript - Does Spread Syntax create a shallow copy or a deep copy? - Stack Overflow
The spread operator allows you to make a shallow copy. To make a deep copy, use the structuredClone() method. ... So is my example for a shallow copy wrong? let b = a is not considered making a copy in javascript?? More on stackoverflow.com
🌐 stackoverflow.com
Efficient deep copy?

Yes. If you create your own "deep copying" function from scratch you can achieve a good performance.

Something like this: https://github.com/hex13/transmutable/blob/master/copyDeep.js

More on reddit.com
🌐 r/javascript
12
4
April 13, 2018
Two exceptional use cases for the spread operator you may not know of
const obj = { key: 'value', ...(isDog && { woof: true }) }; Instead of using &&, I suggest using an explicit ternary instead: isDog ? { woof: true } : {}. The reason is that, as written above, if isDog is false, then the operation will be ...(false). Spreading a boolean in an object works, because false does not have any enumerable properties. But it's probably not a good idea to rely on that behavior. More on reddit.com
🌐 r/javascript
94
251
September 20, 2019
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Operators › Spread_syntax
Spread syntax (...) - JavaScript - MDN Web Docs - Mozilla
May 22, 2026 - Spread syntax effectively goes one level deep while copying an array. Therefore, it may be unsuitable for copying multidimensional arrays. The same is true with Object.assign() — no native operation in JavaScript does a deep clone. The web API method structuredClone() allows deep copying ...
🌐
Educative
educative.io › answers › what-is-the-spread-operator-in-javascript
What is the spread operator in JavaScript?
The spread operator is commonly used to make deep copies of JS objects. When we have nested arrays or nested data in an object, the spread operator makes a deep copy of top-level data and a shallow copy of the nested data.
🌐
LinkedIn
linkedin.com › pulse › mastering-deep-copying-javascript-utilising-spread-operator-khan
Mastering Deep Copying in Javascript: Utilising Spread Operator & Destructuring
August 8, 2023 - Before we dive into the deep copy magic, let's demystify the spread operator. It's like a magical photocopier for objects. Just like you'd copy-paste a document, the spread operator copies properties from one object into another.
🌐
SitePoint
sitepoint.com › blog › javascript › shallow vs. deep copying in javascript
Shallow vs. Deep Copying in JavaScript — SitePoint
November 5, 2024 - On the other hand, a deep copy creates a new instance of the nested objects, meaning changes made to the nested objects in the copied object will not affect the original object. The spread operator (…) in JavaScript is commonly used for shallow ...
Top answer
1 of 4
97

So, for this problem, you have to understand what is the shallow copy and deep copy.

Shallow copy is a bit-wise copy of an object which makes a new object by copying the memory address of the original object. That is, it makes a new object by which memory addresses are the same as the original object.

Deep copy, copies all the fields with dynamically allocated memory. That is, every value of the copied object gets a new memory address rather than the original object.

Now, what a spread operator does? It deep copies the data if it is not nested. For nested data, it deeply copies the topmost data and shallow copies of the nested data.

In your example,

const oldObj = {a: {b: 10}};
const newObj = {...oldObj};

It deep copy the top level data, i.e. it gives the property a, a new memory address, but it shallow copy the nested object i.e. {b: 10} which is still now referring to the original oldObj's memory location.

If you don't believe me check the example,

const oldObj = {a: {b: 10}, c: 2};
const newObj = {...oldObj};

oldObj.a.b = 2; // It also changes the newObj `b` value as `newObj` and `oldObj`'s `b` property allocates the same memory address.
oldObj.c = 5; // It changes the oldObj `c` but untouched at the newObj



console.log('oldObj:', oldObj);
console.log('newObj:', newObj);
.as-console-wrapper {min-height: 100%!important; top: 0;}
Run code snippetEdit code snippet Hide Results Copy to answer Expand

You see the c property at the newObj is untouched.

How do I deep copy an object.

There are several ways I think. A common and popular way is to use JSON.stringify() and JSON.parse().

const oldObj = {a: {b: 10}, c: 2};
const newObj = JSON.parse(JSON.stringify(oldObj));

oldObj.a.b = 3;
oldObj.c = 4;

console.log('oldObj', oldObj);
console.log('newObj', newObj);
.as-console-wrapper {min-height: 100%!important; top: 0;}
Run code snippetEdit code snippet Hide Results Copy to answer Expand

Now, the newObj has completely new memory address and any changes on oldObj don't affect the newObj.

Another approach is to assign the oldObj properties one by one into newObj's newly assigned properties.

const oldObj = {a: {b: 10}, c: 2};
const newObj = {a: {b: oldObj.a.b}, c: oldObj.c};

oldObj.a.b = 3;
oldObj.c = 4;

console.log('oldObj:', oldObj);
console.log('newObj:', newObj);
.as-console-wrapper {min-height: 100%!important; top: 0;} 
Run code snippetEdit code snippet Hide Results Copy to answer Expand

There are some libraries available for deep-copy. You can use them too.

2 of 4
12

structuredClone() is a new global method for real deep clones, all nested elements of the copy will have new memory addresses.

const obj = { a: "a", nestedObj: { b: "b", c: "c" } };
const newObj = structuredClone(obj);

newObj.a = "different a";
newObj.nestedObj.b = "different b";

obj.nestedObj.c = "original c";

console.log(obj);
console.log(newObj);

// output 
//{ a: 'a', nestedObj: { b: 'b', c: 'original c' } }
//{ a: 'different a', nestedObj: { b: 'different b', c: 'c' } }
Find elsewhere
🌐
DEV Community
dev.to › aditi05 › shallow-copy-and-deep-copy-10hh
Shallow Copy and Deep Copy - DEV Community
July 6, 2022 - Changing one, would not affect the other one. Common methods like Array.concat(), Array.from(), Object.assign(), etc creates a shallow copy. Spread(...) operator, creates a deep copy when there is no nesting.
🌐
Bitstack
blog.bitsrc.io › shallow-copy-and-deep-copy-in-javascript-d0ca570cd4cf
Shallow Copy vs Deep Copy in JavaScript | by Jason Kuffler | Bits and Pieces
March 13, 2022 - For nested objects the spread operator will provide a deep copy to the first instance of the values but leaves all the nested data as shallow copies sharing a space in memory with original.
🌐
Envato Tuts+
code.tutsplus.com › home › coding fundamentals
The Best Way to Deep Copy an Object in JavaScript | Envato Tuts+
March 8, 2022 - While the age property in the original object remained untouched, the city property was mutated by the reassignment operation. Hence, the Object.assign() method should be used to deep copy objects that have no nested objects. Another way to deep copy objects in JavaScript is with the ES6 spread operator.
🌐
Opeldo
subrata.hashnode.dev › js-spread-operator
JavaScript spread operator (...), deep copy, shallow copy
April 26, 2023 - So for nested objects, the spread operator provides a deep copy of the first instance (first level of the nest) of the value, but leaves all nested data as shallow copies that share the same space (same references) in memory with the original data.
🌐
Medium
medium.com › @suchitkore1528 › efficient-way-to-deep-copy-objects-and-nested-objects-in-javascript-da73d5778c86
Efficient Way to Deep Copy Objects And Nested Objects in JavaScript | by Suchitkore | Medium
September 14, 2023 - A Deep Copy is a copy that creates a new object with a new memory location to store the object and all of its properties. You can see it in the image. It means that if you make changes in the cloned object, it will not affect the original object.
🌐
Stackademic
blog.stackademic.com › understanding-shallow-and-deep-copies-in-javascript-with-the-spread-operator-3f33228e8922
Understanding Shallow and Deep Copies in JavaScript with the Spread Operator | by Krijesh PV | Stackademic
September 5, 2024 - The Spread Operator in JavaScript The spread operator (…) is a handy feature in JavaScript that allows you to quickly copy or combine objects and arrays. However, understanding how it performs shallow and deep copies is essential to use it effectively.
🌐
Medium
medium.com › @ss751170 › javascript-spread-operator-confusion-shallow-vs-deep-copy-explained-3ee00671809e
🧠 JavaScript Spread Operator Confusion: Shallow vs Deep Copy Explained! | by Shubham Sharma | Medium
July 23, 2025 - To truly separate obj2 from obj, especially for nested objects, you need a deep copy. let obj2 = JSON.parse(JSON.stringify(obj)); ⚠️ But this has limitations: — Doesn’t handle functions — Skips undefined, Symbol, etc. Use libraries like Lodash: import cloneDeep from “lodash/cloneDeep”; let obj2 = cloneDeep(obj); Works like a charm for most cases! The spread operator is great — but don’t expect it to deeply copy nested objects.
Top answer
1 of 3
13

A variable can contain either a value (in case of primitive values, like 1), or a reference (in case of objects, like { food: "pasta" }. Primitive types can only be copied, and since they contain no properties, the shallow/deep distinction does not exist.

If you considered references themselves as primitive values, b = a is a copy of a reference. But since JavaScript does not give you direct access to references (like C does, where the equivalent concept is a pointer), refering to copying a reference as "copy" is misleading and confusing. In context of JavaScript, "copy" is a copy of a value, and a reference is not considered a value.

For non-primitive values, there are three different scenarios:

  • Coreferences, as created by b = a, merely point to the same object; if you modify a in any way, b is affected the same way. Intuitively you'd say that whichever object you modify it is reflected in the copy, but it would be wrong: there is no copy, there is just one object. Regardless of which reference you access the object from, it is the same entity. It is like slapping Mr. Pitt, and wondering why Brad is mad at you — Brad and Mr. Pitt are the same person, not clones.

let a = {
    food: "pasta",
    contents: {
        flour: 1,
        water: 1
    }
}
let b = a;
a.taste = "good";
a.contents.flour = 2;
console.log(b);

  • Shallow copy makes a copy of an object, but any properties that contain references remain so — resulting in coreferent properties. If you change either object, the other is not affected; but if you change any object that is refered to by a property, you will see the change in the other as well. In this example, you will see b.contents.flour is affected by the change in a (because b.contents and a.contents refer to the same object, { flour: 1, water: 2 }), but a.taste does not exist (since a and b are objects in their own right).

let a = {
    food: "pasta",
    contents: {
        flour: 1,
        water: 1
    }
}
let b = {...a};
a.taste = "good";
a.contents.flour = 2;
console.log(b);

  • Deep copy copies each property as well, recursively, so that there are no coreferences — whatever happens to the original object and its properties, the copy is not affected. Here, both b.taste and b.contents.flour are unaffected by changes in a.

let a = {
    food: "pasta",
    contents: {
        flour: 1,
        water: 1
    }
}
let b = structuredClone(a);
a.taste = "good";
a.contents.flour = 2;
console.log(b);

Note that at this time structuredClone is still pretty new; if any users are using older browsers, you might need to use a polyfill.

2 of 3
3

The spread operator allows you to make a shallow copy. To make a deep copy, use the structuredClone() method.

So in your case it would look like this:

let a = {
    food: "pasta",
    restaurantName: "myPastPlace"
}

let b = structuredClone(a);

Read more: https://developer.mozilla.org/en-US/docs/Web/API/structuredClone

🌐
GeeksforGeeks
geeksforgeeks.org › javascript › how-to-deep-clone-in-javascript
How to Deep clone in JavaScript? - GeeksforGeeks
July 23, 2025 - Unlike shallow cloning, deep cloning requires copying all levels of the object’s structure. The Spread operator allows an iterable to expand in places where 0+ arguments are expected.
🌐
LinkedIn
linkedin.com › pulse › demystifying-javascripts-spread-operator-guide-pradeepa-kannan
"Demystifying JavaScript's Spread Operator: A Comprehensive Guide"
September 18, 2023 - The spread operator is a versatile feature in JavaScript that simplifies many common programming tasks by providing an elegant way to work with iterable data structures. Limitation or consideration when using spread operator : Shallow Copying: When used to copy objects or arrays, the spread operator performs a shallow copy. This means that it only creates copies of the top-level elements, not nested objects or arrays. If you have deeply ...
🌐
Runebook.dev
runebook.dev › en › docs › javascript › operators › spread_syntax
A Guide to JavaScript's Spread Operator: Problems and Solutions
Why it happens The spread operator copies the references to the objects, not the objects themselves. So both arrays are pointing to the same objects in memory. How to avoid it To create a deep copy (a completely separate copy of both the array ...
🌐
JavaScript in Plain English
javascript.plainenglish.io › shallow-copy-and-deep-copy-in-javascript-a0a04104ab5c
A Deep Dive into Shallow Copy and Deep Copy in JavaScript | by Ayush Verma | JavaScript in Plain English
April 26, 2021 - It is actually pretty easy to avoid needing to deep copy in JavaScript — if you can just never nest objects and arrays inside each other. Because in that case — where there is no nesting and the objects and arrays only contain primitive values — making a shallow copy with the spread operator (…), .slice(), and .assign() all work great.