Найти тему
JavaСкриптизёр

JavaScript глубокое и поверхностное копирование

Оглавление
Глубокое и поверхностное копирование
Глубокое и поверхностное копирование

Привет!

В этой статье хочу провести сравнение глубокого и поверхностного копирования, чтобы показать разницу и понять когда их использовать.

Копия означает, что вы создаете новый идентичный элемент со своими свойствами из оригинала, и вы ожидаете, что исходный элемент останется таким же, когда вы измените эту копию.

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

Вначале нам нужно понять концепцию передачи по значению и передачи по ссылке.

Передача по значению и по ссылке

Есть два способа передачи и копирования: один по значению, а другой по ссылке. Когда вы копируете что-то по значению, это означает, что вы создаете новое отдельное и независимое значение, подобное оригиналу - глубокая копия( Deep Copy ).

Но когда вы копируете что-то по ссылке, вы создаете просто псевдоним оригинала, а не новую или независимую копию - поверхностную копию( Shallow copy ).

Глубокое копирование

Когда вы создаете глубокую копию, вы создаете идентичную копию исходного элемента с его свойствами.

Оригинал и копия не связаны, что означает, если вы изменили свойства оригинала, это не повлияет на скопированный элемент и не изменит его.

Поверхностное копирование

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

Таким образом, когда вы меняете оригинал, это также повлияет и изменит скопированный, и то же самое, если вы изменили что-то в скопированном элементе, это же что-то изменится и в оригинале.

Схема: разница между глубокой и поверхностной копией
Схема: разница между глубокой и поверхностной копией

Как показано на изображении выше, поверхностная копия все еще связана, но глубоко скопированные элементы имеют разные ссылки и вообще не связаны.

Как создать глубокую копию

Есть много способов копировать объекты, но какой из них является глубоким, а какой поверхностным?

1.Примитивные типы

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

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

2. Объекты

Назначение исходного объекта новой переменной создает поверхностную копию, что означает, что копия - это просто ссылка на оригинальный объект, и любое изменение повлияет на них обоих, как в следующем примере:

Итак, как же создать глубокую копию для объектов?

2.1 Оператор Spread

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

Метод не выполняет глубокой копии вложенных объектов или массивов в оригинальный объект.

2.2 Object.assign

Другой способ глубокого копирования объекта с помощью Object.assign (), который создает совершенно новую и отдельную копию.

Метод не выполняет глубокой копии вложенных объектов или массивов в оригинальный объект.

2.3 JSON.parse() и JSON.stringify()

JSON.stringify() преобразует переданный элемент в строку с форматом JSON. Затем JSON.parse () преобразует его обратно в объект JavaScript, это позволяет выполнять глубокое клонирование и для вложенных объектов, чего не происходит с оператором Object.assign или Spread.

3. Массивы

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

3.1 Оператор Spread

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

Метод не выполняет глубокой копии вложенных объектов или массивов в оригинальный массив.

3.2 map, filter, reduce

Эти методы помогают создать глубокую копию массива, возвращая новый массив, не связанный с оригиналом.

Метод не выполняет глубокой копии вложенных объектов или массивов в оригинальный массив.

3.3 JSON.parse() и JSON.stringify()

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

Заключение

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

Если вам нужно обновлять оригинал, вы можете использовать поверхностную копию, которая следует концепции передачи по ссылке, в противном случае вы можете использовать глубокую копию, которая следует концепции передачи по значению.

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

Спасибо за просмотр!
Если вам понравилась статья - можете оценить её, а также задать свой вопрос в комментариях, я на них отвечаю.
Если хотите больше контента по JavaScript - можете перейти на мой канал и подписаться, чтобы не пропускать новых публикаций.