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

Как поместишь объект в другую ячейку памяти, не ссылаясь на него?

2.0 Middle🔥 141 комментариев
#JavaScript Core

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

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

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

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

Этот вопрос касается создания копии объекта, чтобы изменения в копии не влияли на оригинал. В JavaScript есть несколько способов достичь этого.

Глубокое копирование (Deep Copy)

Самый надёжный способ - это глубокое копирование, которое создаёт полностью независимую копию объекта со всеми его вложенными свойствами.

// 1. JSON метод - простой, но имеет ограничения
const original = { name: "John", address: { city: "Moscow" } };
const copy = JSON.parse(JSON.stringify(original));

copy.address.city = "SPB";
console.log(original.address.city); // "Moscow" - оригинал не изменился!

// Ограничения: не работает с функциями, Date, undefined, Map и т.д.

Рекурсивная функция копирования

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

function deepCopy(obj, seen = new WeakMap()) {
  // Базовые типы
  if (obj === null || typeof obj !== "object") {
    return obj;
  }
  
  // Предотвращение циклических ссылок
  if (seen.has(obj)) {
    return seen.get(obj);
  }
  
  // Массивы
  if (Array.isArray(obj)) {
    const arr = [];
    seen.set(obj, arr);
    for (let i = 0; i < obj.length; i++) {
      arr[i] = deepCopy(obj[i], seen);
    }
    return arr;
  }
  
  // Объекты
  const copy = {};
  seen.set(obj, copy);
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      copy[key] = deepCopy(obj[key], seen);
    }
  }
  return copy;
}

const user = { name: "Alice", hobbies: ["reading", "coding"] };
const userCopy = deepCopy(user);
userCopy.hobbies.push("gaming");
console.log(user.hobbies); // ["reading", "coding"] - оригинал не изменился

Поверхностное копирование (Shallow Copy)

Для простых объектов без вложенных структур используй поверхностное копирование:

// Способ 1: Object.assign()
const original = { name: "John", age: 30 };
const copy1 = Object.assign({}, original);

// Способ 2: Spread оператор (рекомендуется)
const copy2 = { ...original };

// Способ 3: Array.from() для массивов
const arr = [1, 2, 3];
const arrCopy = [...arr];

// Все способы создают новый объект в памяти
original.name = "Jane";
console.log(copy2.name); // "John" - не изменилась

Структурированное клонирование для сложных типов

Для работы с Date, Map, Set и другими специальными типами:

// structuredClone() - встроенный API (современный)
const original = {
  name: "John",
  created: new Date("2024-01-01"),
  tags: new Set(["js", "react"])
};

const copy = structuredClone(original);
copy.created.setFullYear(2025);
console.log(original.created.getFullYear()); // 2024

// Полностью независимые копии всех типов

Выбор метода в зависимости от сценария

Простые объекты - spread оператор:

const user = { name: "John" };
const userCopy = { ...user };

Вложенные объекты - structuredClone():

const config = { db: { host: "localhost", port: 5432 } };
const configCopy = structuredClone(config);

Класс с методами - кастомный метод clone():

class User {
  constructor(name, email) {
    this.name = name;
    this.email = email;
  }
  
  clone() {
    return new User(this.name, this.email);
  }
}

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

Как поместишь объект в другую ячейку памяти, не ссылаясь на него? | PrepBro