Skip to main content

Копирование объектов и ссылки

💥 При копировании переменной объекта копируется ссылка, но сам объект не дублируется.

let user = { name: 'John' };

let admin = user;

admin.name = 'Pete'; // изменено по ссылке из переменной "admin"

alert(user.name); // 'Pete', изменения видны по ссылке из переменной "user"

Сравнение по ссылке

Два объекта равны только в том случае, если это один и тот же объект.

a и b ссылаются на один и тот же объект, поэтому они равны:

let a = {};
let b = a; // копирование по ссылке

alert( a == b ); // true, обе переменные ссылаются на один и тот же объект
alert( a === b ); // true

Здесь два независимых объекта не равны, даже если они выглядят одинаково (оба пусты):

let a = {};
let b = {}; // два независимых объекта

alert( a == b ); // false

Клонирование и объединение, Object.assign

Есть 2 вида копирования shallow - поверхностное и deep - глубокое

Перебор всех свойств объекта через цикл или рекурсию (shallow / deep)

let user = {
name: "John",
age: 30
};

let clone = {}; // новый пустой объект

// давайте скопируем все свойства user в него
for (let key in user) {
clone[key] = user[key];
}

// теперь clone это полностью независимый объект с тем же содержимым
clone.name = "Pete"; // изменим в нём данные

alert( user.name ); // все ещё John в первоначальном объекте

Готовая реализация, через например _.cloneDeep(obj) из библиотеки JavaScript lodash.

Метод Object.assign (shallow)

Object.assign(dest, [src1, src2, src3...])

Оператор расширения {...obj} (shallow)

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

JsonParse (deep)

Cамый простой способ скопировать объект со всеми уровнями вложенности, не копирует методы:

let clone = JSON.parse(JSON.stringify(obj))

Метод structuredClone (deep)

Мы можем использовать глобальный метод structuredClone(), который позволяет сделать полную копию объекта. К сожалению он поддерживается только современными браузерами.

🚀 Источник: https://learn.javascript.ru/object-copy