Какие знаешь методы копирования в JavaScript?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Методы копирования в JavaScript
В JavaScript существует несколько подходов к копированию данных, и выбор конкретного метода зависит от типа данных (примитивы или объекты/массивы), а также от требуемой глубины копирования — поверхностное или глубокое.
Копирование примитивных значений
Для примитивных типов (string, number, boolean, null, undefined, symbol, bigint) копирование происходит автоматически при присваивании, так как они передаются по значению. Это означает, что создаётся независимая копия:
let a = 10;
let b = a; // Создаётся копия значения
b = 20;
console.log(a); // 10 (значение 'a' не изменилось)
Поверхностное копирование объектов и массивов
Для ссылочных типов (object, array, function) при присваивании передаётся ссылка, поэтому для создания копии требуются специальные методы:
1. Spread-оператор (...)
Современный и наиболее популярный способ для массивов и объектов:
// Для массивов
const originalArray = [1, 2, [3, 4]];
const copiedArray = [...originalArray];
// Для объектов
const originalObj = { a: 1, b: { c: 2 } };
const copiedObj = { ...originalObj };
Важно: создаёт только поверхностную копию — вложенные объекты/массивы остаются ссылками.
2. Object.assign()
Метод для копирования свойств объектов:
const original = { x: 1, y: 2 };
const copy = Object.assign({}, original);
Также создаёт поверхностную копию. Первый аргумент — целевой объект, в который копируются свойства.
3. Методы массивов
Для массивов можно использовать slice() или concat():
const arr = [1, 2, 3];
const copy1 = arr.slice(); // Способ 1
const copy2 = [].concat(arr); // Способ 2
Оба метода также создают поверхностные копии.
Глубокое копирование
Для создания полностью независимой копии, включая все вложенные структуры, используют:
1. JSON.parse(JSON.stringify())
Классический, но ограниченный способ:
const obj = { a: 1, b: { c: 2 } };
const deepCopy = JSON.parse(JSON.stringify(obj));
Ограничения: не копирует функции, undefined, Symbol, Map, Set, Date (преобразуется в строку), циклические ссылки вызывают ошибку.
2. Рекурсивная функция
Кастомная реализация для полного контроля:
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') return obj;
if (obj instanceof Date) return new Date(obj);
if (obj instanceof Array) return obj.map(item => deepClone(item));
const clonedObj = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
clonedObj[key] = deepClone(obj[key]);
}
}
return clonedObj;
}
3. Библиотечные методы
В популярных библиотеках:
- Lodash:
_.cloneDeep(value) - jQuery:
$.extend(true, {}, original)
4. Нативные API
structuredClone()(доступен в современных средах):
const obj = { a: 1, b: { c: 2 } };
const clone = structuredClone(obj); // Нативное глубокое копирование
Поддерживает больше типов данных, чем JSON-подход, включая Map, Set, Date, RegExp, ArrayBuffer, но всё равно не копирует функции.
Сравнение методов в таблице
| Метод | Тип копирования | Поддерживаемые типы | Производительность |
|---|---|---|---|
Spread/Object.assign() | Поверхностный | Объекты, массивы | Высокая |
slice()/concat() | Поверхностный | Только массивы | Высокая |
JSON.parse/stringify | Глубокий | JSON-совместимые типы | Средняя |
structuredClone() | Глубокий | Большинство типов, кроме функций | Высокая |
| Рекурсивный обход | Глубокий | Любые типы (настраиваемо) | Низкая/средняя |
| Библиотечные методы | Глубокий | Зависит от библиотеки | Зависит от реализации |
Практические рекомендации
-
Для примитивов — простое присваивание достаточно.
-
Для поверхностного копирования плоских структур — используйте spread-оператор или
Object.assign(). -
Для глубокого копирования:
- В современных приложениях —
structuredClone() - Для JSON-совместимых данных —
JSON.parse(JSON.stringify()) - В сложных случаях — библиотеки типа Lodash или кастомные реализации
- В современных приложениях —
-
Важные нюансы:
- Глубокое копирование ресурсоёмко для больших объектов
- Циклические ссылки требуют специальной обработки
- Прототипы и дескрипторы свойств не копируются большинством методов
Выбор метода всегда зависит от конкретной задачи, требуемой производительности и структуры копируемых данных.