Что такое мелкая копия и глубокая копия в JavaScript?

Опубликовано: 1 Декабря, 2021

JavaScript - это высокоуровневый язык сценариев на стороне клиента с динамической типизацией. JavaScript добавляет функциональность статическим HTML-страницам. Как и большинство других языков программирования, JavaScript поддерживает концепции глубокого и поверхностного копирования.

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

Реализация кода

Javascript

var employee = {
eid: "E102" ,
ename: "Jack" ,
eaddress: "New York" ,
salary: 50000
}
console.log( "Employee=> " , employee);
var newEmployee = employee; // Shallow copy
console.log( "New Employee=> " , newEmployee);
console.log( "---------After modification----------" );
newEmployee.ename = "Beck" ;
console.log( "Employee=> " , employee);
console.log( "New Employee=> " , newEmployee);
// Name of the employee as well as
// newEmployee is changed.

Выход:

Объяснение: Из приведенного выше примера видно, что когда имя newEmployee изменяется, оно также отражается для старого объекта сотрудника. Это может вызвать несогласованность данных. Это называется мелкой копией. Вновь созданный объект имеет тот же адрес памяти, что и старый. Следовательно, любое изменение, внесенное в любой из них, изменяет атрибуты для обоих. Чтобы решить эту проблему, используется глубокая копия. Если один из них удалить из памяти, другой перестает существовать. В некотором смысле эти два объекта взаимозависимы.

Глубокая копия: в отличие от мелкой копии, глубокая копия создает копию всех членов старого объекта, выделяет отдельную область памяти для нового объекта, а затем назначает скопированные элементы новому объекту. Таким образом, оба объекта независимы друг от друга, и в случае любого изменения одного из них это не влияет на другой. Кроме того, если один из объектов будет удален, другой останется в памяти. Теперь для создания глубокой копии объекта в JavaScript мы используем методы JSON.parse () и JSON.stringify (). Давайте рассмотрим пример, чтобы лучше понять это.

Реализация кода:

Javascript

var employee = {
eid: "E102" ,
ename: "Jack" ,
eaddress: "New York" ,
salary: 50000
}
console.log( "=========Deep Copy========" );
var newEmployee = JSON.parse(JSON.stringify(employee));
console.log( "Employee=> " , employee);
console.log( "New Employee=> " , newEmployee);
console.log( "---------After modification---------" );
newEmployee.ename = "Beck" ;
newEmployee.salary = 70000;
console.log( "Employee=> " , employee);
console.log( "New Employee=> " , newEmployee);

Выход:

Объяснение: Здесь новый объект создается с помощью методов JSON.parse () и JSON.stringify () JavaScript. JSON.stringify () принимает объект JavaScript в качестве аргумента и затем преобразует его в строку JSON. Эта строка JSON передается методу JSON.parse (), который затем преобразует ее в объект JavaScript. Этот метод полезен, когда объект небольшой и имеет сериализуемые свойства. Но если объект очень большой и содержит определенные несериализуемые свойства, существует риск потери данных. Особенно, если объект содержит методы, тогда JSON.stringify () завершится ошибкой, поскольку методы не сериализуемы. Существуют более эффективные способы глубокого клонирования, одним из которых является Lodash, который также позволяет использовать методы клонирования.

Lodash To Deep Copy: Lodash - это библиотека JavaScript, которая предоставляет несколько служебных функций, и одной из наиболее часто используемых функций библиотеки Lodash является метод cloneDeep (). Этот метод помогает в глубоком клонировании объекта, а также клонирует несериализуемые свойства, которые были ограничением в подходе JSON.stringify ().

Реализация кода

Javascript

const lodash = require( 'lodash' );
var employee = {
eid: "E102" ,
ename: "Jack" ,
eaddress: "New York" ,
salary: 50000,
details: function () {
return "Employee Name: "
+ this .ename + "-->Salary: "
+ this .salary;
}
}
var deepCopy = lodash.cloneDeep(employee);
console.log( "Original Employee Object" );
console.log(employee);
console.log( "Deep Copied Employee Object" );
console.log(deepCopy);
deepCopy.eid = "E103" ;
deepCopy.ename = "Beck" ;
deepCopy.details = function () {
return "Employee ID: " + this .eid
+ "-->Salary: " + this .salary;
}
console.log( "----------After Modification----------" );
console.log( "Original Employee Object" );
console.log(employee);
console.log( "Deep Copied Employee Object" );
console.log(deepCopy);
console.log(employee.details());
console.log(deepCopy.details());

Выход:

Объяснение: Оба объекта после модификации имеют разные свойства. Кроме того, методы каждого объекта определены по-разному и производят разный вывод.