0

I know 10 different ways to clone an Array in Javascript, but none of them works as I want... Let me explain :

This is my array : const a = [1, new Date(), false, { date: new Date(), name: "John Doe" }]

Old For loop

const b = [];
for(let i = 0, len = a.length; i < len; i++) b[i] = a[i];
console.log(b); --> [ 1, Date Wed Jul 19 2023 10:35:21 GMT+0200 (heure d’été d’Europe centrale), false, { date: Date Wed Jul 19 2023 10:35:21 GMT+0200 (heure d’été d’Europe centrale), name: "John Doe" } ]
b[3].date = null;
console.log(a[3]); --> { date: null, name: "John Doe" }

So as you can see, it cloned well the Array, but when I manipulate the object inside the array, it changes the value in the initial array too

All other methods

All the other methods I know gave me the exact same problem

  1. Map method : const b = a.map(x => x)
  2. From method : const b = Array.from(a)
  3. From + map method : const b = Array.from(a, x => x)
  4. Slice method : const b = a.slice()
  5. Spread operator method : const b = [ ...a ]
  6. Concat method : const b = a.concat([])
  7. Of method : const b = Array.of(...a)
  8. Object Assign method : const b = Object.assign([], a)

JSON method

Fortunately there is one way to clone it loosing the refs which is :

const b = JSON.parse(JSON.stringify(a))
b[3].date = null
console.log(a[3]) --> { date: Date Wed Jul 19 2023 10:35:21 GMT+0200 (heure d’été d’Europe centrale), name: "John Doe" }
console.log(b) --> [ 1, "2023-07-19T08:35:21.419Z", false, { date: null, name: "John Doe" } ]

BUT as you can see, the problem is that my old Date type is now a String and I can't manipulate it as a Date ... So it's not identical ...

So what ?

Do you know any other method doing the job or should I write my own recursive method to clone an array and their object ?

Thanks a lot for your time and your help !

Simon Trichereau
  • 721
  • 11
  • 19
  • 1
    Does this answer your question? [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) – evolutionxbox Jul 19 '23 at 08:46
  • 1
    @RoryMcCrossan yeah so I have to use the JSON method, then looping the initial array and its values (and looping inside the values if necesary) and if the value is a special Type, typing the clone value ... So ok, I have to make a recursive function... It's just we are in 2023 and there isn't a native method doing the job :O – Simon Trichereau Jul 19 '23 at 08:50
  • 1
    If you read the answers you can found out that there is actually a native js method to do exactly what you want – Florent M. Jul 19 '23 at 08:53
  • Yes, I just saw :) Thanks for your help ! – Simon Trichereau Jul 19 '23 at 08:55

2 Answers2

0

Actually, there is one function that can do the trick for you: structuredClone

const a = [1, new Date(), false, { date: new Date(), name: "John Doe" }];

const b = structuredClone(a);

console.log(a === b) // false

b[3] = null;

console.log(a) 
// [
//    1,
//    "2023-07-19T08:46:59.195Z",
//    false,
//    {
//      "date": "2023-07-19T08:46:59.195Z",
//      "name": "John Doe"
//    }
// ]

console.log(b)
// [
//    1,
//    "2023-07-19T08:46:59.195Z",
//    false,
//    null
// ]
Florent M.
  • 1,107
  • 1
  • 6
  • 14
0

structuredClone

const a = [1, new Date(), false, { date: new Date(), name: "John Doe" }]
const b = structuredClone(a)
b[3].date = null
console.log(a)
console.log(typeof b[1], b[1] instanceof Date)
Konrad
  • 21,590
  • 4
  • 28
  • 64