Найти в Дзене

Ошибки при копировании объектов в JavaScript.


И снова простая, на первый взгляд, задача имеет подводные камни о которых мало кто задумывается. Копирование объектов, что может быть проще:
const someItemList = [
{ name: 'Product 1', value: 'Some value 1' },
{ name: 'Product 2', value: 'Some value 2' },
]
const newItemList = [...someItemList]

Существует два типа копирования - поверхностное и глубокое. Первое работает быстро, и обычно его вполне достаточно, проблемы начинаются при копировании вложенных структур. Если изменить свойство объекта в новом массиве newItemList, то эти изменения будут видны и в исходном массиве someItemList.

Причина - способ хранения данных, когда разные объекты ссылаются на одну ячейку памяти:
console.log(someItemList[1] === newItemList[1]) // true

Как решить данную задачу? Рассмотрим несколько вариантов:

1. Функция structuredClone() для глубокого копирования:
const deep = structuredClone(someItemList)
console.log(someItemList[1] === deep[1]) // false

2. Функция глубокого копирования из библиотеки утилит lodash:
import cloneDeep from 'lodash.clonedeep'
const deep = cloneDeep(someItemList)
console.log(someItemList[1] === deep[1]) // false

3. Ещё один способ — сериализовать объект в JSON и распарсить его:
const deep = JSON.parse(JSON.stringify(someItemList))
console.log(someItemList[1] === deep[1]) // false

Ошибки при копировании объектов в JavaScript.  И снова простая, на первый взгляд, задача имеет подводные камни о которых мало кто задумывается.
1 минута