Во-первых, есть два типа данных: примитивные типы данных и ссылочные типы данных Примитивные типы данных (логические, байтовые, char, короткие, int, длинные, с плавающей запятой и двойные), а ссылочные типы данных - ( Массив и объект)

Значение, присвоенное переменной примитивного типа данных, тесно связано. Это означает, что всякий раз, когда вы создаете копию переменной с примитивным типом данных, значение копируется в новую ячейку памяти, на которую указывает новая переменная. Когда вы сделаете копию, это будет настоящая копия. Давайте посмотрим на пример:

let a = 5
let b = a // this is the copy
b = 6
console.log(b) // 6
console.log(a) // 5

Выполняя let b = a, вы делаете копию значения a. Теперь, когда вы переназначаете новое значение переменнойb, значение переменной b изменяется, но не переменной a. Эти значения фактически сохраняются только один раз при создании экземпляра.

В то время как для ссылочного типа данных он хранит адрес места в памяти, где хранится объект. Существует два типа копирования ссылочных типов данных, а именно неглубокая копия и глубокая копия.

Мелкая копия

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

Когда значение поля является ссылочным типом, оно просто копирует ссылочный адрес, новый объект не создается. Таким образом, указанные объекты становятся общими.

let originalObject= {name: "apple", type: "fruit"}
 if
   let clonedObject= originalObject
 then
   clonedObject= {name: "apple", type: "fruit"}

Здесь есть два объекта: originalObject и clonedObject, clonedObject имеет ссылку на originalObject. Если один из этих объектов изменяется (из originalObject или clonedObject), мы можем наблюдать изменение значения другого.

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

Однако есть обходной путь для копирования объектов без ссылки. Метод Object.assign () копирует перечисляемые свойства из исходного объекта в целевой объект. Кроме того, это можно использовать, только если объект / массив содержит значения примитивного типа.

Пример 1:

let originalObject = {name: "apple"};
let clonedObject = Object.assign({}, originalObject);

В приведенном выше примере clonedObject копируется из originalObject. Однако originalObject и clonedObject - это два объекта, указывающие на два разных адреса памяти, а не на один и тот же адрес памяти.

Здесь, если вы измените значение любого свойства переменной originalObject или clonedObject, это не повлияет на другое.

Пример 2:

let originalObject = {name: "apple", price: {chennai: 120}}
let clonedObject = Object.assign({}, originalObject)

Теперь clonedObject копирует все значения из originalObject, но originalObject содержит цену, которая является ссылочным типом (объектом). Таким образом, изменение свойства примитивного типа (name) clonedObject не повлияет на свойство originalObject, но изменение свойства ссылочного типа (price ) из clonedObject или originalObject будут влиять друг на друга.

clonedObject.name ="orange"; // will not reflect in originalObject
clonedObject.price.chennai = "100"; // will reflect in  
                                       originalObject also

Таким образом, метод Object.assign () будет скопирован до первого уровня. Если объект содержит какой-либо вложенный объект или массив, тогда внутренне скопированное значение ссылочного типа будет ссылаться на его адрес в памяти. Чтобы преодолеть это, нам нужно повторять и копировать до последнего уровня, но этот подход дорогостоящий и не рекомендуется.

Глубокая копия

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

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

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

Чтобы скопировать объект JavaScript в новую переменную НЕ по ссылке

Для простых объектов JSON самый простой способ:

 var clonedObject = JSON.parse(JSON.stringify(originalObject));

В jQuery вы можете использовать:

// Shallow copy
   var clonedObject = jQuery.extend({}, originalObject);
// Deep copy
   var clonedObject = jQuery.extend(true, {}, originalObject);

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

Francium Tech - это технологическая компания, специализирующаяся на поставке программного обеспечения высочайшего качества и масштабируемости на экстремальных скоростях. Цифры и размер данных нас не пугают. Если у вас есть какие-либо требования или вы хотите бесплатно проверить работоспособность вашей системы или архитектуры, напишите письмо на адрес [email protected], мы свяжемся с вами!