← Назад к вопросам

Какие знаешь методы копирования в JavaScript?

1.8 Middle🔥 141 комментариев
#JavaScript Core#Браузер и сетевые технологии

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Методы копирования в 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()ГлубокийБольшинство типов, кроме функцийВысокая
Рекурсивный обходГлубокийЛюбые типы (настраиваемо)Низкая/средняя
Библиотечные методыГлубокийЗависит от библиотекиЗависит от реализации

Практические рекомендации

  1. Для примитивов — простое присваивание достаточно.

  2. Для поверхностного копирования плоских структур — используйте spread-оператор или Object.assign().

  3. Для глубокого копирования:

    • В современных приложениях — structuredClone()
    • Для JSON-совместимых данных — JSON.parse(JSON.stringify())
    • В сложных случаях — библиотеки типа Lodash или кастомные реализации
  4. Важные нюансы:

    • Глубокое копирование ресурсоёмко для больших объектов
    • Циклические ссылки требуют специальной обработки
    • Прототипы и дескрипторы свойств не копируются большинством методов

Выбор метода всегда зависит от конкретной задачи, требуемой производительности и структуры копируемых данных.

Какие знаешь методы копирования в JavaScript? | PrepBro