Клонирование объектов в JavaScript — это создание копии объекта, которая не ссылается на исходный объект в памяти. Существует несколько способов клонирования, каждый из которых имеет свои особенности: поверхностное или глубокое копирование, поддержка различных типов данных, производительность.
Основные методы клонирования:
Клонирование объектов — важная концепция в JavaScript, позволяющая создавать независимые копии данных. Правильный выбор метода зависит от требований к глубине копирования и типов данных в объекте.
Копирует только перечисляемые свойства первого уровня:
const original = { a: 1, b: { c: 2 } };
const copy = Object.assign({}, original);Современный синтаксис для поверхностного копирования:
const copy = { ...original };Простой способ глубокого копирования с ограничениями:
const deepCopy = JSON.parse(JSON.stringify(original));Полноценное глубокое копирование всех типов данных:
function deepClone(obj) {
// Реализация рекурсивного копирования
}Современный API браузера для глубокого копирования:
const deepCopy = structuredClone(original);const user = {
name: 'Иван',
address: {
city: 'Москва',
street: 'Ленина'
}
};
// Поверхностное копирование
const shallow = { ...user };
shallow.address.city = 'Санкт-Петербург';
// Исходный объект тоже изменится!
// Глубокое копирование
const deep = structuredClone(user);
deep.address.city = 'Казань';
// Исходный объект не изменитсяconst data = {
items: [1, 2, { value: 3 }]
};
// Разные методы дают разные результаты
const assignCopy = Object.assign({}, data);
const spreadCopy = { ...data };
const jsonCopy = JSON.parse(JSON.stringify(data));// ❌ Использование spread для глубокого копирования
const config = {
database: {
host: 'localhost',
port: 5432
}
};
const copy = { ...config };
copy.database.host = 'remote'; // Изменит и исходный объект!
// ✅ Использование structuredClone для глубокого копирования
const deepCopy = structuredClone(config);// ❌ JSON-методы не работают с функциями, undefined, Symbol
const obj = {
func: () => {},
undef: undefined,
sym: Symbol('test'),
date: new Date()
};
const copy = JSON.parse(JSON.stringify(obj));
// Функции, undefined и Symbol будут потеряны!
// ✅ Использование structuredClone
const properCopy = structuredClone(obj);Правильный выбор метода клонирования зависит от структур данных, требований к производительности и поддерживаемых браузеров.
Какой будет результат и почему?
const original = {
name: 'Тест',
data: {
value: 42,
nested: {
flag: true
}
},
tags: ['js', 'clone'],
func: function() { return this.name; }
};
// Метод 1
const copy1 = { ...original };
// Метод 2
const copy2 = JSON.parse(JSON.stringify(original));
// Метод 3
const copy3 = structuredClone(original);
// Что будет при изменении?
copy1.data.value = 100;
copy2.tags[0] = 'javascript';
copy3.data.nested.flag = false;
console.log(original.data.value);
console.log(original.tags[0]);
console.log(original.data.nested.flag);
console.log(copy2.func);Ответ:
100
javascript
false
undefined
Объяснение:
copy1 (spread-оператор):
copy1.data остается ссылкой на original.datacopy1.data.value влияет на original.data.valueoriginal.data.value становится 100copy2 (JSON-методы):
copy2.tags — независимая копия массиваcopy2.tags[0] не влияет на original.tags[0]original.tags[0] остается ‘js’copy2.func будет undefined, так как функции теряются при JSON-сериализацииcopy3 (structuredClone):
copy3.data.nested — независимая копияcopy3.data.nested.flag не влияет на original.data.nested.flagoriginal.data.nested.flag остается true❗ Ошибка в анализе выше — пересмотрим:
На самом деле:
original.data.value будет 100 (изменено через copy1)original.tags[0] останется ‘js’ (copy2.tags — независимая копия)original.data.nested.flag останется true (copy3.data.nested — независимая копия)copy2.func будет undefined (функции теряются в JSON)Правильный результат:
100
js
true
undefined
Этот пример демонстрирует важные различия между методами клонирования:
Хотите больше статей для подготовки к собеседованиям? Подписывайтесь на EasyAdvice, добавляйте сайт в закладки и совершенствуйтесь каждый день 💪