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

Какие знаешь ограничения на использования Object.assign?

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

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

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

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

Ограничения использования Object.assign в JavaScript

Object.assign() — мощный метод для копирования свойств объектов, но он имеет несколько важных ограничений, которые каждый Frontend-разработчик должен понимать.

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

Самое критичное ограничениеObject.assign() создает только поверхностную копию объекта. Если свойства исходного объекта содержат вложенные объекты, они копируются по ссылке, а не рекурсивно.

const original = {
  name: 'John',
  address: {
    city: 'Moscow',
    street: 'Tverskaya'
  }
};

const copy = Object.assign({}, original);
copy.address.city = 'Saint Petersburg';

console.log(original.address.city); // 'Saint Petersburg' - оригинал изменен!

Это может привести к непреднамеренным мутациям исходных данных, что особенно опасно при работе с состоянием в React/Vue.

2. Копирование только перечисляемых собственных свойств

Object.assign() копирует только перечисляемые (enumerable) и собственные (own) свойства объектов. Не перечисляемые свойства (например, свойства из прототипа) игнорируются.

const parent = { inheritedProp: 'from prototype' };
const obj = Object.create(parent);
obj.ownProp = 'own property';

// Делаем свойство неперечисляемым
Object.defineProperty(obj, 'hiddenProp', {
  value: 'hidden value',
  enumerable: false
});

const copy = Object.assign({}, obj);
console.log(copy); // { ownProp: 'own property' }
// inheritedProp и hiddenProp не скопированы

3. Проблемы с геттерами и сеттерами

При копировании из источника, содержащего геттеры, Object.assign() копирует результат выполнения геттера, а не сам геттер как функцию.

const source = {
  get currentDate() {
    return new Date().toISOString();
  }
};

const target = Object.assign({}, source);
console.log(typeof target.currentDate); // 'string', а не 'function'
// Геттер превратился в обычное свойство со значением

4. Ошибки при копировании из null и undefined

Object.assign() выбрасывает ошибку, если любой из исходных параметров равен null или undefined.

// Object.assign({}, null); // TypeError: Cannot convert undefined or null to object
// Object.assign({}, undefined); // Та же ошибка

// Обходное решение:
const safeCopy = Object.assign({}, obj || {});

5. Перезапись свойств без предупреждения

Свойства перезаписываются в порядке передачи аргументов без каких-либо предупреждений:

const target = { a: 1, b: 2 };
const source1 = { b: 3, c: 4 };
const source2 = { b: 5, d: 6 };

const result = Object.assign(target, source1, source2);
console.log(result); // { a: 1, b: 5, c: 4, d: 6 }
// Свойство b было перезаписано дважды

6. Отсутствие глубокого копирования Symbol-свойств

Хотя Object.assign() копирует Symbol-свойства, он также делает это поверхностно:

const sym = Symbol('id');
const original = {
  [sym]: { value: 123 }
};

const copy = Object.assign({}, original);
copy[sym].value = 456;
console.log(original[sym].value); // 456 - оригинал изменен

7. Производительность при большом количестве свойств

При копировании объектов с огромным количеством свойств Object.assign() может быть менее эффективным, чем специализированные решения.

Альтернативы и решения

Для преодоления этих ограничений существуют различные подходы:

  • Глубокое копирование: использование рекурсивных функций или библиотек
// Наивная реализация глубокого копирования (без учета edge cases)
function deepCopy(obj) {
  if (obj === null || typeof obj !== 'object') return obj;
  if (obj instanceof Date) return new Date(obj);
  if (obj instanceof Array) return obj.map(deepCopy);
  
  const copy = {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      copy[key] = deepCopy(obj[key]);
    }
  }
  return copy;
}

// Использование готовых решений
import { cloneDeep } from 'lodash';
const deepCopy = cloneDeep(original);
  • Spread оператор (тоже поверхностное копирование):
const copy = { ...original };
  • Современные API браузеров:
// Глубокое копирование через structuredClone (доступен не везде)
if (typeof structuredClone === 'function') {
  const deepCopy = structuredClone(original);
}

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

  1. Всегда проверяйте, нужна ли вам глубокая или поверхностная копия
  2. Тестируйте с edge cases: null, undefined, вложенные объекты
  3. Используйте TypeScript для лучшего контроля типов при копировании
  4. Документируйте в коде, когда используется Object.assign() и почему

Понимание этих ограничений критически важно для написания надежного кода, особенно при работе с состоянием приложений, иммутабельными структурами данных и функциональным программированием.

Какие знаешь ограничения на использования Object.assign? | PrepBro