Clone an Array of Objects

origen of idea:

It always happens that without realizing it, we instantiate a variable and forget that we are not really defining a copy, but a pointer. this can be programmatic problem when dealing with an array of objects. I have the doubt which is the best solution to this. in the same way, propose a syntax to solve it.

the clon keyword, which would basically do a json.stringify and a json.parse together

clon myClonedVar = myComplexObject; // equal to JSON.parse(JSON.stringify(myComplexObject));
myClonedVar.car[0].color = "red";
myClonedVar.car[0].color == myComplexObject.car[0].color; // false

I understand that it is not a syntax problem, but I would like to know your opinions and solutions when we talk about complex objects

my favorite solution is and I think the most effective is:

let myClonedVar = JSON.parse(JSON.stringify(myComplexObject));

but it consumes many resources

It also corrupts functions, regexes, symbols, undefined, Dates, and many other things.

There isn't a generic way to "clone" every JS object, whether builtin or from userland, so I'm not sure how this could be solved short of introducing a Symbol protocol for such cloning.

3 Likes

A function that goes through each attribute and sub-attribute of each object and array, storing their properties to replicate them? I imagine it would have poor performance.

How do you imagine an engine would be able to do it significantly faster?

1 Like

OP didn't do a great job of explaining it, but think of how V8 normally stores objects.

  • Type map (includes prototype and fast property keys+details)
  • Pointer to properties dictionary (list of key+value+details)
  • Pointer to elements array (for indexed properties)
  • Pointer for each immediate fast property

Normally, to clone, you'd be iterating through each individual key, looking each key up and then storing them to a new object. V8 instead could drastically shortcut that process for non-proxy objects by:

  1. Creating a new object with the same type map and fast values.
  2. Cloning the properties and elements arrays (via standard GC allocation + C memcpy) to newly allocated fixed arrays.
  3. Iterating through the fast properties and the properties and elements arrays and replacing relevant non-objects with their newly cloned selves.
  4. In case the order above doesn't match the spec order, you can just queue a list of pointers to assign to + object + clone method reference as necessary and iterate that after addressing the rest.

This algorithm involves zero property lookups, in effect turning an amortized O(n) to a true O(n) process with a substantially reduced constant factor for most (if not all) plain objects. Arrays are a similar story, and engines already optimize for the first step of that to a degree.

1 Like