0

I wanted to deep copy some objects in javascript so that my reducer is pure in redux. Some properties have 1 level of nesting and some have 2 and some have 3 like:

var x = {a:9}, y:{a:{b:9}}, z = {a:{b:{c:9}}};

So should I use some other technique like:

var newX = {...x}, newY = {a:{...y.a}}

Should I continue to use the same technique in a loop - write my custom deep copy for 3 level nesting also or should I simply use:

var newZ = JSON.parse(JSON.stringify(z));

to create my deep copy.

What is the fastest way alternative to JSON.parse(JSON.stringify(value))??

Hafeez Hamza
  • 794
  • 3
  • 16
Probosckie
  • 1,585
  • 4
  • 25
  • 40
  • 3
    Possible duplicate of [What is the most efficient way to deep clone an object in JavaScript?](https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript) – Vignesh Raja Nov 10 '18 at 03:47
  • 1
    If your using it in redux reducer, best way is normalize the state, do not nest object, in redux documentation itself says that [link](https://redux.js.org/basics/reducers), if you explain your situation with more practical code I can help you. – Hafeez Hamza Nov 10 '18 at 03:54

2 Answers2

0

If you truly want deep cloning, the most performant way by far in my experience is the JSON parse/stringify trick you already mentioned.

Otherwise you'll have to fall back to some sort of recursive cloning strategy. Lodash has a deepClone function for example.

As an alternative to deep cloning, I highly recommend immer, which leverages a concept called structural sharing, in which unchanged parts of the object aren't cloned. This is more performant and uses less memory.

greim
  • 9,149
  • 6
  • 34
  • 35
0

I use this function found somewhere on StackOverflow:

const deepCopy = origin => {
  let cp;
  switch (typeof origin) {
    case 'object':
      if (origin === null) {
        cp = null;
      } else {
        switch (toString.call(origin)) {
          case '[object Array]':
            cp = origin.map(deepCopy);
            break;
          case '[object Date]':
            cp = new Date(origin);
            break;
          case '[object ReqExp]':
            cp = new RegExp(origin);
            break;

          default:
            cp = Object.keys(origin).reduce((prev, key) => {
              prev[key] = deepCopy(origin[key]);
              return prev;
            }, {});
            break;
        }
      }
      break;

    default:
      cp = origin;

  }
  return cp;
}
AlbertS
  • 706
  • 5
  • 12