Skip to main content

Object.preventExtensions() у JavaScript

Object.preventExtensions() це вбудований метод JavaScript, який забороняє додавати до об'єкта нові властивості, але дозволяє змінювати і видаляти вже наявні. Це найм'якша форма захисту об'єкта, на відміну від seal() і freeze().

Теорія

TL;DR

  • Object.preventExtensions(obj) забороняє додавати нові властивості.
  • Наявні властивості можна змінювати і можна видаляти.
  • Дескриптори configurable, writable, enumerable лишаються без змін.
  • Перевірка стану: Object.isExtensible(obj) поверне false.
  • Заборона поширюється і на Object.defineProperty(), який кине TypeError.
  • Успадковані через прототип властивості лишаються доступними.

Швидкий приклад

javascript
const user = { name: 'Alice', age: 25 }; Object.preventExtensions(user); user.city = 'Kyiv'; // не додасться delete user.age; // можна видалити user.name = 'Oleh'; // можна змінити console.log(user); // { name: 'Oleh' }

Після Object.preventExtensions():

  • не можна додати нові властивості;
  • можна видалити старі;
  • можна міняти наявні значення.

Синтаксис і перевірка стану

javascript
Object.preventExtensions(obj)
АргументОпис
objОб'єкт, до якого не можна буде додати нові властивості

Повертає сам об'єкт, уже нерозширюваний, тобто це не копія.

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

Object.isExtensible(obj) повертає false, якщо до об'єкта не можна додавати нові властивості. Операція незворотна: зробити об'єкт розширюваним назад неможливо.

Що відбувається «під капотом»

Object.preventExtensions(obj) робить таке:

  • забороняє додавання нових властивостей, зокрема й через Object.defineProperty();
  • наявні властивості лишаються змінюваними та видаляними;
  • configurable, writable, enumerable не чіпаються.

Спроба додати властивість через defineProperty не мовчить, а кидає помилку:

javascript
const obj = {}; Object.preventExtensions(obj); try { Object.defineProperty(obj, 'x', { value: 1 }); } catch (err) { console.log('Помилка:', err.message); }

Виведе:

javascript
Помилка: Cannot define property x, object is not extensible

Звичайне присвоєння obj.x = 1 поводиться інакше: у нестрогому режимі воно мовчки нічого не робить, а в 'use strict' теж кидає TypeError.

Відмінності від seal() і freeze()

МетодМожна додаватиМожна видалятиМожна змінюватиДескриптори configurable
preventExtensions()НіТакТакБез змін
seal()НіНіТакУсі configurable: false
freeze()НіНіНіУсі configurable: false, writable: false

Тобто preventExtensions() це найм'якший варіант захисту. Він просто «закриває вхід», але не заважає працювати з тим, що вже є.

Прототипи і успадковані властивості

javascript
const parent = { role: 'user' }; const child = Object.create(parent); Object.preventExtensions(child); child.name = 'Alice'; // не додасться console.log(child.name); // undefined console.log(child.role); // "user", успадковано з прототипу

preventExtensions() не впливає на успадковані властивості, вони лишаються доступними через прототип. Обмежується лише набір власних властивостей конкретного об'єкта; сам прототип, якщо його не захистити окремо, спокійно можна розширювати, і нові поля одразу стануть видимими для child.

Підсумкова таблиця:

ПоведінкаДозволено?
Додавати нові властивостіНі
Видаляти наявніТак
Змінювати значенняТак
Міняти дескрипториТак
ПеревіркаObject.isExtensible(obj)

Типові помилки

  • Очікувати, що об'єкт стане незмінним. preventExtensions() не боронить ні запис, ні delete; для цього потрібні seal() або freeze().
  • Чекати виключення від звичайного присвоєння. obj.x = 1 у нестрогому режимі мовчки провалюється, помилку ви побачите лише під 'use strict' або від Object.defineProperty().
  • Сподіватися відкотити захист. Зробити об'єкт розширюваним назад не можна, стан незворотний.
  • Забувати про прототип. Захищено лише власні властивості; додавання полів у прототип і далі впливає на об'єкт.
  • Вважати дію глибокою. Вкладені об'єкти лишаються повністю розширюваними, їх треба обробляти окремо.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.