Що таке property descriptor?
Що таке Property Descriptor
Property Descriptor (дескриптор властивості) - це внутрішній об'єкт, який описує поведінку властивості об'єкта: чи можна її змінювати, перелічувати, видаляти, і чи має вона геттер/сеттер.
Простіше кажучи:
Це "метадані" про властивість - не лише її значення, а й флаги, що визначають, як із нею можна працювати.
Види властивостей у JS
Властивості бувають двох типів:
- Data Property (властивість-дані)
→ зберігає конкретне значення (
value) - Accessor Property (властивість-аксесор)
→ визначає функції
getта/абоset
Структура дескриптора
Для властивості-даних:
javascript
{
value: any, // значення
writable: boolean, // чи можна змінювати value
enumerable: boolean, // чи видно при переборі (for...in, Object.keys)
configurable: boolean // чи можна видаляти або змінювати дескриптор
}Для властивості-аксесора:
javascript
{
get: function | undefined, // геттер
set: function | undefined, // сеттер
enumerable: boolean,
configurable: boolean
}Приклад: отримати дескриптор
javascript
const user = { name: 'Tim' };
const descriptor = Object.getOwnPropertyDescriptor(user, 'name');
console.log(descriptor);Виведе:
javascript
{
value: 'Tim',
writable: true,
enumerable: true,
configurable: true
}Усі ці флаги за замовчуванням дорівнюють true, якщо властивість створена звичайним чином.
Приклад: задати властивість вручну
javascript
const user = {};
Object.defineProperty(user, 'role', {
value: 'admin',
writable: false, // не можна змінювати значення
enumerable: false, // не з'являється при переборі
configurable: false // не можна видалити чи переналаштувати
});
console.log(user.role); // 'admin'
user.role = 'user';
console.log(user.role); // 'admin' - значення не змінилосьПеревіримо перелічуваність і конфігурованість
javascript
const user = {};
Object.defineProperty(user, 'name', {
value: 'Tim',
enumerable: false,
configurable: false
});
console.log(Object.keys(user)); // [] - не перелічується
delete user.name; // не видалиться
console.log(user.name); // 'Tim'Приклад з геттером і сеттером
javascript
const person = {};
let _age = 25;
Object.defineProperty(person, 'age', {
get() {
return _age;
},
set(value) {
if (value < 0) throw new Error('Вік не може бути від\'ємним');
_age = value;
},
enumerable: true,
configurable: true
});
console.log(person.age); // 25
person.age = 30; // викликає setter
console.log(person.age); // 30Масове визначення властивостей
javascript
const user = {};
Object.defineProperties(user, {
name: {
value: 'Alex',
writable: true,
enumerable: true
},
age: {
value: 25,
writable: false
}
});Отримати всі дескриптори об'єкта
javascript
const obj = { a: 1, b: 2 };
console.log(Object.getOwnPropertyDescriptors(obj));Результат:
javascript
{
a: { value: 1, writable: true, enumerable: true, configurable: true },
b: { value: 2, writable: true, enumerable: true, configurable: true }
}Застосування в реальних задачах
- Створення "read-only" властивостей
javascript
Object.defineProperty(config, 'API_KEY', {
value: '12345',
writable: false
});- Приховані властивості
javascript
Object.defineProperty(obj, '_id', {
value: 42,
enumerable: false
});- Реалізація реактивності
(наприклад, Vue.js використовує
get/setу дескрипторах для відстеження змін) - Імітація приватних полів (до появи
#)
javascript
Object.defineProperty(obj, 'secret', {
value: 'hidden',
enumerable: false
});Підсумок
| Властивість дескриптора | Для чого потрібна |
|---|---|
value | саме значення |
writable | чи можна змінити value |
enumerable | чи видно при переборі |
configurable | чи можна видалити/перевизначити |
get | функція-геттер |
set | функція-сеттер |
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.