简体   繁体   中英

How do I clone a JavaScript object?

In the function formatHours() below, I am trying to assign newHours to selectedLocation.data.hours (an object)

I am using the spread operator to clone the object, so that when the function finishes selectedLocation.data.hours remains the same, but it doesn't. After this function runs, selectedLocationd.data.hours is now equal to newHours .

formatHours():

const formatHours = () => {
    // ERROR: trying to clone selectedLocation.data.hours, but not working
    const newHours = { ...selectedLocation.data.hours };

    // loop through all hours and convert them to javascript date with .toDate()
    for (const hour in newHours) {
      newHours[hour][0] = newHours[hour][0].toDate();
      newHours[hour][1] = newHours[hour][1].toDate();
    }

    // set hours state with updated hours
    setHours(newHours);
  };  

Here's what selectedLocation.data.hours looks like BEFORE passing it through formatHours() :

(object of arrays of Firebase Firestore timestamps)

在此处输入图像描述

Here's what selectedLocation.data.hours looks like AFTER passing it through formatHours() :

(object of arrays of Javascript Date objects)

在此处输入图像描述

NOTE: selectedLocation.data.hours should stay the same before and after the function, but doesn't. I must be missing something.

Instead of changing the newHours[hour] array (which mutates the object currently in state/props), create an entirely new array at that location, with the properties you need:

// Shallow clone newHours
const newHours = { ...selectedLocation.data.hours };
// Reassign each property; it'll affect the clone, not the original
for (const [hour, arr] of Object.entries(newHours)) {
  newHours[hour] = [
    arr[0].toDate(),
    arr[1].toDate(),
    arr[2]
  ];
}

Another method, with Object.fromEntries :

const newHours = Object.fromEntries(
    Object.entries(selectedLocation.data.hours).map(([hour, arr]) => (
        [ // return an entry array
            hour, // key in new object
            [ // value in new object
                arr[0].toDate(),
                arr[1].toDate(),
                arr[2]
            ]
        ]
    ))
);

I'm not sure if it's the best way to do that, but you can do this

 const newHours = JSON.parse(JSON.stringify(selectedLocation.data.hours));

This will deep clone the object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM