Даже если вы не знали об этом, вы, скорее всего, уже имели дело с копиями в JavaScript. Возможно, вы также слышали о парадигме функционального программирования, согласно которой вы не должны изменять уже собранные данные. Для этого вы должны понимать, как безопасно копировать значения в JavaScript.
Прежде чем мы углубимся в значения копирования, мы должны понять типы данных в JavaScript.
Переменные используются в качестве контейнера/хранилища данных в программировании. Последний стандарт ECMAScript определяет восемь типов данных,
Семь типов данных, которые являются примитивами:
- Логическое значение:
true
иfalse
. - null: специальное ключевое слово, обозначающее нулевое значение. (Поскольку JavaScript чувствителен к регистру,
null
не совпадает сNull
,NULL
или любым другим вариантом.) - undefined: свойство верхнего уровня, значение которого не определено.
- Число: целое число или число с плавающей запятой. Например:
42
или3.14159
. - BigInt: целое число произвольной точности. Например:
9007199254740992n
. - Строка: последовательность символов, представляющая текстовое значение. Например:
"Howdy"
. - Symbol: тип данных, экземпляры которого уникальны и неизменны.
В JavaScript есть только один непримитивный/составной тип данных:
- Объект. Объекты можно рассматривать как набор свойств. Значения свойств могут быть значениями любого типа, включая другие объекты, что позволяет создавать сложные структуры данных. Свойства идентифицируются с помощью значений key. например. объекты, массивы, функции.
Это будет настоящая копия, когда мы будем делать копии примитивных типов данных.
eg.
В приведенном выше примере b является копией a, изменение a не повлияет на значение b.
Если то же самое относится к непримитивным типам, то изменение исходного объекта повлияет на значения клонированного объекта. Потому что типы объектов относятся к адресу памяти, а не к значениям.
eg.
В приведенном выше примере clonedObj является копией obj, изменение в obj повлияет на свойства в clonedObj.
Неглубокое копирование
Неглубокая копия объекта — это копия, свойства которой имеют те же ссылки (указывают на те же базовые значения), что и исходный объект, из которого была сделана копия. В результате, когда вы меняете источник или копию, вы также можете вызвать изменение другого объекта — и, таким образом, вы можете в конечном итоге непреднамеренно вызвать изменения в источнике или копии, которых вы не ожидаете.
Поверхностная копия — это побитовая копия объекта. Если мы делаем поверхностную копию объекта, то значения примитивных типов копируются, адреса памяти копируются для непримитивных/ссылочных типов.
Этого можно добиться с помощью Object.assign, оператора Spread для объектов и concat, from и slice метод массива для массивов.
При использовании сторонней библиотеки помогут методы расширения jQuery, клонирования подчеркивания, клонирования lodash.
eg.
Глубокое копирование
Глубокая копия объекта — это копия, свойства которой не имеют тех же ссылок (указывающих на те же базовые значения), что и исходный объект, из которого была сделана копия. В результате, когда вы меняете либо источник, либо копию, вы можете быть уверены, что вы не вызываете изменения и другого объекта; то есть вы не будете непреднамеренно вносить изменения в источник или копию, которых не ожидаете.
Deep Copy копирует все поля и предоставляет новый адрес памяти всем значениям ссылочного типа.
Метод объекта JSON
Этого можно добиться, передав объект методу JSON.stringify, а затем передав это значение методу JSON.parse. Но у этого метода есть некоторые проблемы с производительностью.
Метод расширения jQuery
клон lodashГлубокий метод
Это также может быть достигнуто с помощью метода cloneDeep от lodash/расширения jquery. Если вы используете lodash/jquery в своем приложении, то было бы хорошо, иначе использовать библиотеку lodash/jquery только для глубокого клонирования было бы громоздко.
В этом случае вы можете сделать служебную функцию для достижения этого следующим образом:
Глобальный метод structuredClone()
создает глубокий клон заданного значения, используя алгоритм структурированного клонирования.