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

Можно ли сделать объект в JavaScript с неизменяемыми свойствами?

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

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

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

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

Да, объект с неизменяемыми свойствами в JavaScript создать можно

В JavaScript существует несколько механизмов для создания объектов с неизменяемыми (immutable) свойствами, которые отличаются по степени защиты и гибкости. Рассмотрим основные подходы.

1. Использование Object.freeze()

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

const user = {
  name: "Анна",
  age: 30
};

Object.freeze(user);

// Попытки изменений будут игнорироваться или вызовут ошибку в strict mode
user.name = "Мария"; // Не сработает
user.city = "Москва"; // Не сработает
delete user.age; // Не сработает

console.log(user); // { name: "Анна", age: 30 }

Важные особенности Object.freeze():

  • Делает объект полностью неизменяемым (нельзя добавлять, удалять или изменять свойства)
  • Действует только на первый уровень объекта (вложенные объекты остаются изменяемыми)
  • Возвращает тот же объект, который был передан в метод
  • В strict mode попытки изменения вызовут TypeError

2. Использование Object.seal()

Метод Object.seal() менее строгий, чем freeze - он позволяет изменять значения существующих свойств, но запрещает добавлять новые или удалять существующие.

const config = {
  apiUrl: "https://api.example.com",
  timeout: 5000
};

Object.seal(config);

config.timeout = 10000; // Работает - можно изменять значения
config.retryCount = 3; // Не сработает - нельзя добавлять свойства
delete config.apiUrl; // Не сработает - нельзя удалять свойства

console.log(config); // { apiUrl: "https://api.example.com", timeout: 10000 }

3. Использование Object.preventExtensions()

Самый мягкий способ - Object.preventExtensions() запрещает только добавление новых свойств, но позволяет изменять и удалять существующие.

const car = {
  brand: "Toyota",
  year: 2020
};

Object.preventExtensions(car);

car.year = 2021; // Работает
delete car.brand; // Работает
car.color = "red"; // Не сработает

console.log(car); // { year: 2021 }

4. Определение свойств с дескрипторами

Для точечного контроля можно использовать Object.defineProperty() или Object.defineProperties(), которые позволяют настроить дескрипторы каждого свойства:

const immutableObject = {};

Object.defineProperties(immutableObject, {
  id: {
    value: 12345,
    writable: false,      // Запретить изменение значения
    enumerable: true,     // Видимость в циклах
    configurable: false   // Запретить удаление и переопределение
  },
  createdAt: {
    value: new Date(),
    writable: false,
    configurable: false
  }
});

// Альтернативный синтаксис для одного свойства
Object.defineProperty(immutableObject, 'version', {
  value: '1.0.0',
  writable: false,
  enumerable: true,
  configurable: false
});

5. Глубокое замораживание объектов

Поскольку Object.freeze() работает только на поверхностном уровне, для полной неизменяемости нужна рекурсивная реализация:

function deepFreeze(obj) {
  // Получаем имена всех свойств объекта
  const propNames = Object.getOwnPropertyNames(obj);
  
  // Замораживаем сам объект
  Object.freeze(obj);
  
  // Рекурсивно замораживаем все свойства-объекты
  for (const name of propNames) {
    const value = obj[name];
    
    if (value && typeof value === 'object' && !Object.isFrozen(value)) {
      deepFreeze(value);
    }
  }
  
  return obj;
}

const appState = {
  user: {
    name: "Иван",
    settings: {
      theme: "dark",
      notifications: true
    }
  }
};

deepFreeze(appState);

// Теперь даже вложенные объекты защищены
appState.user.settings.theme = "light"; // Не сработает

6. Практические рекомендации и ограничения

Когда использовать неизменяемые объекты:

  • Для конфигурационных объектов, которые не должны меняться во время выполнения
  • В качестве константных значений
  • В функциональном программировании для предотвращения побочных эффектов
  • Для защиты важных данных от случайных изменений

Ограничения и особенности:

  • Все эти методы не защищают от присваивания нового значения переменной
  • Производительность: частое использование Object.freeze() может повлиять на производительность
  • Сравнение объектов: замороженные объекты не становятся примитивами, для сравнения нужно использовать другие подходы
  • В современных фреймворках (React, Redux) неизменяемость данных - ключевая концепция, но реализуется через создание новых объектов, а не модификацию существующих

Заключение

JavaScript предоставляет несколько уровней контроля над изменяемостью объектов, от полного замораживания до точечной настройки свойств. Выбор метода зависит от конкретных требований: нужна ли полная неизменяемость или только защита от определенных операций. В современных приложениях, особенно построенных на принципах функционального программирования, работа с неизменяемыми структурами данных становится стандартом для повышения надежности и предсказуемости кода.

Можно ли сделать объект в JavaScript с неизменяемыми свойствами? | PrepBro