2

In the following code, I create an array a of objects that each has a property b that is initialized to 0. I copy a into c with the spread operator, hoping that I'll be able to manipulate c without affecting a. However, here's what happens:

let a = [
    {
        b: 0
    },
    {
        b: 0
    },
    {
        b: 0
    },
]
let c = [...a]
c[0].b = 1
console.log(a) // a gets modified when I modify c

I understand why this happens: since the elements of a are objects, their reference is copied when I create c, so the elements of c still refer to the corresponding elements of a.

Does anyone know a way to solve this? What I want is a way to copy a and manipulate the properties of the objects in the resulting array without modifying the corresponding objects in a.

Thanks!

Possible Solution

I know you can do JSON.parse(JSON.stringify(a)), but I'm wondering if there's a less hacky solution :)

Why this is different from Copy array by value

The Copy array by value article asks about copying an array of primitives, in which the solution is the either use slice() or the spread operator. I've done that here, and the problem is different, as described in the question.

UPDATE: SOLUTION

As @talemyn pointed out, although Copy array by value is a different question, the second highest voted response to that question goes into detail about deep copying, and from that, it seems the best solution for this use case is JSON.parse(JSON.stringify(c)). Thanks!

gkeenley
  • 6,088
  • 8
  • 54
  • 129
  • 2
    why not stringify and parse the object? – Nina Scholz May 22 '19 at 20:59
  • @RandyCasburn I added a comment explaining why these questions are different. – gkeenley May 22 '19 at 21:01
  • @NinaScholz I added a comment addressing that. That does work, but I'm wondering if there's a cleaner solution :) So far though, that's the cleanest I've found. – gkeenley May 22 '19 at 21:02
  • 1
    @gkeenley - while the questions are different, take a look at the second highest voted answer ( https://stackoverflow.com/a/23536726/1281907 ), which goes into a **lot** of detail around the different was to copy arrays. – talemyn May 22 '19 at 21:02
  • Don't stringify, https://stackblitz.com/edit/typescript-qmzgf7 – Adrian Brand May 23 '19 at 00:04
  • const clone = obj => Array.isArray(obj) ? obj.map(item => clone(item)) : obj instanceof Date ? new Date(obj.getTime()) : obj && typeof obj === 'object' ? Object.getOwnPropertyNames(obj).reduce((o, prop) => { o[prop] = clone(obj[prop]); return o; }, {}) : obj; – Adrian Brand May 23 '19 at 00:06

0 Answers0