Skip to main content

Прапорці writable, enumerable, configurable

Прапорці writable, enumerable і configurable це три службові параметри в дескрипторі властивості (property descriptor), які керують поведінкою властивостей об'єктів у JavaScript. Під час звичайної роботи з об'єктом вони непомітні, але саме вони визначають, чи можна властивість змінити, видалити або перерахувати.

Теорія

TL;DR

ПрапорецьЩо робитьЗа замовчуванням
writableДозволяє змінювати значення властивостіfalse (якщо властивість створено через defineProperty)
enumerableРобить властивість видимою під час перебору (for...in, Object.keys)false
configurableДозволяє видаляти властивість і змінювати її прапорціfalse
  • Звичайне присвоєння obj.key = value створює властивість з усіма прапорцями true.
  • Прочитати прапорці можна через Object.getOwnPropertyDescriptor(obj, key).
  • Задати їх можна лише через Object.defineProperty(obj, key, descriptor).

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

javascript
const user = {}; Object.defineProperty(user, 'name', { value: 'Alice', writable: false, // не можна змінювати enumerable: false, // не з'являється в циклах configurable: false // не можна видалити або змінити прапорці }); console.log(user.name); // "Alice" user.name = 'Bob'; // не змінюється delete user.name; // не видаляється console.log(Object.keys(user)); // [] бо властивість не перераховується

writable: чи можна змінювати значення

javascript
const user = {}; Object.defineProperty(user, 'age', { value: 25, writable: false }); user.age = 30; // не спрацює console.log(user.age); // 25
  • writable: true дозволяє змінювати значення;
  • writable: false робить властивість лише для читання.

У нестрогому режимі запис у таку властивість просто мовчки ігнорується, у strict mode кидається TypeError.

enumerable: чи показувати властивість під час перебору

javascript
const user = {}; Object.defineProperty(user, 'secret', { value: '12345', enumerable: false }); console.log(user.secret); // доступно напряму console.log(Object.keys(user)); // [] бо властивість не видно for (const key in user) console.log(key); // нічого не виведе
  • enumerable: true робить властивість видимою у for...in, Object.keys(), JSON.stringify();
  • enumerable: false робить її «прихованою».

Приклад з реального життя: вбудовані методи (toString, valueOf) мають enumerable: false, щоб не заважати під час перебору.

configurable: чи можна видалити або змінити прапорці

javascript
const user = {}; Object.defineProperty(user, 'id', { value: 10, configurable: false }); delete user.id; // не видалиться console.log(user.id); // 10 // Спробуємо змінити writable: Object.defineProperty(user, 'id', { writable: true }); // TypeError: Cannot redefine property: id
  • configurable: true дозволяє видалити властивість або змінити її прапорці;
  • configurable: false забороняє видалення і зміну enumerable, configurable та перехід writable з false на true.

Єдине, що ще можна змінити у такої властивості, це writable з true на false, але не навпаки.

Як прочитати і як задати прапорці

Прочитати:

javascript
const obj = { name: 'Alice' }; const descriptor = Object.getOwnPropertyDescriptor(obj, 'name'); console.log(descriptor);

Виведе:

javascript
{ value: 'Alice', writable: true, enumerable: true, configurable: true }

Задати:

javascript
Object.defineProperty(obj, 'prop', { value: 42, writable: false, enumerable: true, configurable: false });

Підсумок:

ПрапорецьПризначенняПриклад
writableЧи можна змінювати значення властивостіuser.age = 30
enumerableЧи видно властивість під час переборуObject.keys(user)
configurableЧи можна видалити або перевизначити властивістьdelete user.prop

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

  • Забувати, що defineProperty ставить усі прапорці у false. Властивість, створена без явного enumerable: true, зникає з Object.keys() і з результату JSON.stringify().
  • Чекати на помилку від запису у writable: false. Без 'use strict' присвоєння мовчки не спрацьовує, і баг помічають пізно.
  • Плутати writable: false з незмінністю об'єкта. Якщо у властивості лежить об'єкт, його поля все одно можна змінювати; глибока заморозка це вже Object.freeze по всьому дереву.
  • Розраховувати повернути configurable у true. Це незворотна операція, тому спершу продумують, які властивості справді треба «запечатати».
  • Вважати, що enumerable: false приховує дані. Властивість і далі читається напряму і видима для Object.getOwnPropertyNames() та Reflect.ownKeys().
  • Використовувати спред або Object.assign для копіювання. Вони переносять лише перераховувані власні властивості і втрачають прапорці; для точної копії потрібні Object.getOwnPropertyDescriptors і Object.defineProperties.

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

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

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