Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Object.preventExtensions() у JavaScript». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`Object.preventExtensions()` забороняє додавати до об'єкта нові властивості, але дозволяє змінювати і видаляти вже наявні.** Це найм'якша форма захисту: дескриптори `configurable`, `writable` та `enumerable` лишаються недоторканими, а перевірити стан можна через `Object.isExtensible(obj)`, який поверне `false`. Успадковані через прототип властивості метод не зачіпає. ```javascript const user = { name: 'Alice', age: 25 }; Object.preventExtensions(user); user.city = 'Kyiv'; // не додасться delete user.age; // можна видалити user.name = 'Oleh'; // можна змінити console.log(user); // { name: 'Oleh' } ``` **Ключове:** метод «закриває вхід» для нових властивостей і більше нічого не обмежує.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**`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()`. - **Сподіватися відкотити захист.** Зробити об'єкт розширюваним назад не можна, стан незворотний. - **Забувати про прототип.** Захищено лише власні властивості; додавання полів у прототип і далі впливає на об'єкт. - **Вважати дію глибокою.** Вкладені об'єкти лишаються повністю розширюваними, їх треба обробляти окремо.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.