Learn JavaScript

Object.preventExtensions() - метод для запрета расширения объекта в JavaScript

Object.preventExtensions() запрещает расширять объект.

После этого в объект уже нельзя добавлять новые свойства, но существующие свойства обычно ещё можно менять и удалять.

Синтаксис

Object.preventExtensions(obj)

obj - объект, для которого нужно запретить расширение.

Что делает Object.preventExtensions()

Метод делает объект нерасширяемым.

const user = {
  name: "Anna",
};

Object.preventExtensions(user);

user.age = 25;

console.log(user); // { name: "Anna" }

Новое свойство age здесь уже не добавилось.

Что возвращает Object.preventExtensions()

Object.preventExtensions() возвращает тот же самый объект.

const user = { name: "Anna" };
const result = Object.preventExtensions(user);

console.log(result === user); // true

Это важно: метод не создаёт копию, а работает с существующим объектом.

Нельзя добавлять новые свойства

Это главная задача метода.

const settings = {
  theme: "dark",
};

Object.preventExtensions(settings);

settings.lang = "ru";

console.log(settings.lang); // undefined

Обычно можно менять существующие свойства

Если свойство уже есть и оно записываемое, его значение обычно можно менять.

const user = {
  name: "Anna",
};

Object.preventExtensions(user);

user.name = "Ivan";

console.log(user.name); // "Ivan"

Это одно из главных отличий от Object.freeze().

Обычно можно удалять свойства

Если свойство конфигурируемое, его обычно всё ещё можно удалить.

const user = {
  name: "Anna",
};

Object.preventExtensions(user);

delete user.name;

console.log(user.name); // undefined

То есть метод запрещает только расширение объекта, а не вообще любые изменения.

В strict mode будет ошибка

В обычном режиме попытка добавить новое свойство обычно просто не срабатывает.

В строгом режиме JavaScript выбросит ошибку.

"use strict";

const user = { name: "Anna" };

Object.preventExtensions(user);

// user.age = 25; // TypeError

Как проверить состояние

Для этого есть Object.isExtensible().

const user = { name: "Anna" };

console.log(Object.isExtensible(user)); // true

Object.preventExtensions(user);

console.log(Object.isExtensible(user)); // false

Это самый прямой способ проверить, можно ли ещё добавлять свойства.

Object.preventExtensions() и Object.seal()

Эти методы похожи, но seal() строже.

Object.preventExtensions():

  • запрещает добавлять новые свойства
  • обычно позволяет удалять существующие свойства
  • обычно позволяет менять значения существующих свойств

Object.seal():

  • тоже запрещает добавлять новые свойства
  • дополнительно запрещает удалять существующие свойства

То есть seal() строже, чем preventExtensions().

Object.preventExtensions() и Object.freeze()

freeze() ещё строже.

Object.preventExtensions():

  • запрещает только добавление новых свойств

Object.freeze():

  • запрещает добавление новых свойств
  • запрещает удаление свойств
  • запрещает изменение значений существующих свойств

Поэтому preventExtensions() - самый мягкий вариант из этой тройки.

Массивы и Object.preventExtensions()

Массив тоже является объектом, поэтому метод работает и с ним.

const numbers = [1, 2, 3];

Object.preventExtensions(numbers);

numbers[0] = 10;
numbers.push(4);

console.log(numbers); // [10, 2, 3]

Изменение существующего элемента возможно, а расширение массива уже нет.

Метод работает поверхностно

Как и соседние методы, Object.preventExtensions() действует только на сам объект.

Вложенные объекты внутри остаются обычными.

const user = {
  name: "Anna",
  address: {
    city: "Moscow",
  },
};

Object.preventExtensions(user);

user.address.city = "Paris";

console.log(user.address.city); // "Paris"

Верхний объект больше нельзя расширять, но вложенный address не защищён.

Когда это полезно

Object.preventExtensions() удобно использовать, когда:

  • нужно запретить добавление новых свойств
  • структура объекта уже должна оставаться фиксированной
  • при этом существующие свойства ещё можно менять или удалять

Пример:

const config = {
  version: 1,
};

Object.preventExtensions(config);

config.version = 2;

console.log(config); // { version: 2 }

Object.preventExtensions() не делает объект неизменяемым полностью

Это очень важно не перепутать.

const user = {
  name: "Anna",
};

Object.preventExtensions(user);

user.name = "Ivan";

console.log(user.name); // "Ivan"

Если нужна более жёсткая защита, обычно смотрят в сторону Object.seal() или Object.freeze().

Частые ошибки

Думать, что метод запрещает любые изменения

const user = {
  name: "Anna",
};

Object.preventExtensions(user);
user.name = "Ivan";

console.log(user.name); // "Ivan"

Существующие свойства обычно всё ещё можно менять.

Путать Object.preventExtensions() и Object.seal()

const user = {
  name: "Anna",
};

Object.preventExtensions(user);
delete user.name;

Такое удаление ещё может сработать, а вот после Object.seal() уже нет.

Считать, что защита глубокая

const user = {
  profile: { city: "Moscow" },
};

Object.preventExtensions(user);

user.profile.city = "Paris";

Вложенные объекты внутри всё ещё можно менять.

Быстрая памятка

  • Object.preventExtensions() запрещает добавлять новые свойства
  • метод возвращает тот же самый объект
  • существующие свойства обычно можно менять и удалять
  • проверить состояние можно через Object.isExtensible()
  • это самый мягкий вариант по сравнению с Object.seal() и Object.freeze()

Коротко

Object.preventExtensions() - это способ запретить расширение объекта без полной блокировки остальных изменений. Главное, что стоит запомнить: метод не даёт добавлять новые свойства, но существующие свойства обычно ещё можно менять или удалять.