Введение

Объекты Javascript используются повсеместно и очень широко. Независимо от того, работаете ли вы над созданием приложения из ванильного javascript или используете такие библиотеки, как React, Vue и т. д., они являются наиболее широко используемыми структурами данных в современных приложениях. И не говоря уже о том, насколько они универсальны.

Но у них есть одна проблема!

Если вы пессимист, это будет проблемой, но это скорее особенность, если вы знаете, как использовать эту концепцию объектов в Javascript.

Объекты можно изменять, а их свойства передаются по ссылке, то есть их свойства не хранятся отдельно в памяти. Новая переменная, указывающая на объект, не будет создавать копию, а будет ссылаться на исходное расположение объектов в памяти. Следовательно, изменение второго объекта также изменит первый.

Демонстрация:

Есть два способа обойти это: Object.assign() или использовать оператор расширения {…} для «расширения» или расширения объекта в новую переменную. Это позволит изменить новую переменную без изменения исходной.

Теперь вот улов. Переменная smallObj создает копию originalObj, но создает неглубокую копию, что означает, что smallObj указывает на новое местоположение 2, но ссылается на местоположение 1 для вложенного объекта.

Простым решением этой проблемы является передача значения вложенного объекта вручную, но это может стать громоздким, если объект очень большой.

Самый простой способ обойти это — использовать метод JSON.stringify().

Это создаст глубокую копию объекта.

Глубокая копия копирует все поля и создает копии динамически выделенной памяти, на которую указывают поля.

Шоколадный совет: если вы попытаетесь проверить, равны ли 2 объекта с одинаковыми свойствами с помощью obj1 = obj2, будет возвращено false. Это происходит потому, что каждый объект имеет свой собственный адрес в памяти, как мы узнали. Самый простой способ проверить содержимое объектов на равенство -> JSON.stringify(obj1) === JSON.stringify(obj2).

Но JSON.stringify() имеет свои ограничения.

Это не очень надежно и стандартно, так как при этом происходит потеря данных. При использовании этого метода исходный объект должен быть безопасным для JSON. Мы не должны использовать Date, undefined, Infinity, функции, regexps, карты, наборы или другие сложные типы внутри нашего объекта.

Например: если мы используем JSON.stringify() для даты, то мы получим строковое представление даты в формате ISO из объекта даты, и JSON.parse() не сможет преобразовать его обратно в объект даты.

Так что в итоге ничего не получится. Мы можем создать глубокую копию, написав код с нуля, но это не очень элегантно.

К счастью, у нас есть сторонние облегченные библиотеки, такие как LODASH, которые делают это за нас.

cloneDeep можно импортировать отдельно через модуль lodash.clonedeep и, вероятно, это лучший выбор.

установить npm — сохранить lodash

Заключение

Важно понимать, как глубоко клонировать объекты в JavaScript. Вы создали неглубокие копии объектов, переназначая и перебирая объекты. Вы также использовали библиотеку Lodash для создания поверхностных и глубоких копий объектов.