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

Как сделать поверхностную копию объекта?

1.7 Middle🔥 191 комментариев
#JavaScript Core

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

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

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

Поверхностная копия объекта в JavaScript

Поверхностная копия (shallow copy) — это новый объект, который содержит ссылки на те же значения, что и исходный объект. Это отличается от глубокой копии, где копируются и вложенные объекты.

Разница: поверхностная vs глубокая копия

const original = {
  name: 'Иван',
  address: { city: 'Москва', zip: '101000' }
};

// Поверхностная копия
const shallow = { ...original };
shallow.address.city = 'Спб';
console.log(original.address.city); // 'Спб' — исходный объект изменился!

// Глубокая копия
const deep = JSON.parse(JSON.stringify(original));
deep.address.city = 'Казань';
console.log(original.address.city); // 'Спб' — исходный объект не изменился

Способ 1: Spread оператор (...)

Это самый современный и популярный способ:

const user = { id: 1, name: 'Анна', active: true };
const userCopy = { ...user };

userCopy.name = 'Мария';
console.log(user.name);  // 'Анна' — исходный не изменился
console.log(user === userCopy); // false — разные объекты

Плюсы:

  • Чистый и понятный синтаксис
  • Легко комбинировать с новыми свойствами
  • Работает с массивами: const arr2 = [...arr1]
const updated = { ...user, name: 'Наташа', age: 25 };
// { id: 1, name: 'Наташа', active: true, age: 25 }

Способ 2: Object.assign()

Традиционный метод копирования объектов:

const user = { id: 1, name: 'Боб' };
const userCopy = Object.assign({}, user);

// Или копирование свойств в существующий объект
const target = { role: 'admin' };
Object.assign(target, user);
console.log(target); // { role: 'admin', id: 1, name: 'Боб' }

Особенности:

  • Первый параметр — целевой объект (изменяется)
  • Возвращает целевой объект
  • Копирует перечислимые свойства
const defaults = { theme: 'light', lang: 'ru' };
const userPrefs = { theme: 'dark' };
const config = Object.assign({}, defaults, userPrefs);
console.log(config); // { theme: 'dark', lang: 'ru' }

Способ 3: Object.create() с Object.getOwnPropertyNames()

Для более сложных случаев с дескрипторами свойств:

function shallowCopy(obj) {
  const copy = Object.create(Object.getPrototypeOf(obj));
  Object.getOwnPropertyNames(obj).forEach(prop => {
    copy[prop] = obj[prop];
  });
  return copy;
}

const original = { x: 1, y: 2 };
const copy = shallowCopy(original);

Способ 4: Деструктуризация объекта

Для объектов с известной структурой:

const user = { name: 'Ольга', email: 'olga@example.com', age: 28 };
const { name, email, age } = user;
const userCopy = { name, email, age };

// Или с остатком
const { name, ...rest } = user;
const userWithoutName = rest; // { email: '...', age: 28 }

Способ 5: Array.slice() для массивов

Для массивов (поверхностная копия):

const original = [1, 2, 3];
const copy1 = original.slice();
const copy2 = [...original];

original.push(4);
console.log(copy1); // [1, 2, 3] — не изменилась
console.log(copy2); // [1, 2, 3] — не изменилась

Проблема с вложенными объектами

Поверхностная копия не копирует вложенные объекты и массивы:

const user = {
  name: 'Владимир',
  hobbies: ['чтение', 'спорт'],
  address: { city: 'Москва' }
};

const copy = { ...user };

copy.hobbies.push('путешествия');
copy.address.city = 'Казань';

console.log(user.hobbies); // ['чтение', 'спорт', 'путешествия'] — изменилась!
console.log(user.address.city); // 'Казань' — изменилась!

Для решения нужна глубокая копия:

// JSON способ (простой, но с ограничениями)
const deepCopy = JSON.parse(JSON.stringify(user));

// Рекурсивная функция
function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') return obj;
  if (Array.isArray(obj)) return obj.map(deepClone);
  
  const copy = {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      copy[key] = deepClone(obj[key]);
    }
  }
  return copy;
}

Рекомендация

Для большинства случаев используй spread оператор ({ ...obj }) — это современный стандарт. Для глубокого копирования сложных структур используй библиотеки типа Lodash (_.cloneDeep()) или встроенный structuredClone() (новый API).

Как сделать поверхностную копию объекта? | PrepBro