Что ты знаешь о дескрипторах?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Дескрипторы в JavaScript — это объекты, которые описывают различные свойства свойства объекта, такие как его значение (value), возможность записи (writable), возможность перечисления (enumerable) и возможность конфигурации (configurable). Также есть дескрипторы с геттерами и сеттерами.
Существует два типа дескрипторов:
-
Дескрипторы данных: Содержат значение свойства.
value: Значение свойства. Может быть любым валидным типом данных.writable: Логическое значение. Еслиtrue, значение свойства можно изменить (obj.prop = newValue). По умолчаниюfalseдля accessor-свойств иtrueдля data-свойств, созданных обычным присваиванием.enumerable: Логическое значение. Еслиtrue, свойство будет видно при итерации по свойствам объекта (например, в циклеfor...inили при использованииObject.keys()). По умолчаниюfalseдля свойств, добавленныхObject.defineProperty, иtrueдля свойств, созданных обычным присваиванием.configurable: Логическое значение. Еслиtrue, характеристики дескриптора (кромеvalueиwritableпри их изменении с данными на аксессоры) можно изменять, а само свойство удалять. По умолчаниюfalseдля свойств, добавленныхObject.defineProperty(кромеvalue), иtrueдля свойств, созданных обычным присваиванием. Once configured as non-configurable, cannot be changed back. You can decrease writability from true to false, but not vice versa on a non-configurable getter/setter.
-
Дескрипторы аксессоров: Определяют функции, которые будут вызываться при получении (getter) или установке (setter) значения свойства.
get: Функция, вызываемая при чтении свойства. Результат этой функции становится значением свойства. Не принимает аргументов.set: Функция, вызываемая при записи в свойство. Принимает одно аргумент — новое устанавливаемое значение.enumerable: Логическое значение (аналогично data-дескрипторам).configurable: Логическое значение (аналогично data-дескрипторам).
Дескрипторы нельзя смешивать: у свойства либо есть value и writable, либо get и set.
Дескрипторы используются для управления свойствами объекта на более низком уровне, чем обычное присваивание, в частности через методы Object.defineProperty(), Object.defineProperties(), Object.getOwnPropertyDescriptor(), Object.getOwnPropertyDescriptors(), Object.create().
Пример создания свойства с дескриптором данных:
// Создаем пустой объект
const obj = {};
// Определяем свойство 'name' с дескриптором данных
Object.defineProperty(obj, 'name', {
value: 'Alice',
writable: false, // Свойство нельзя изменить
enumerable: true, // Свойство будет перечисляемым
configurable: false // Характеристики свойства нельзя изменить, свойство нельзя удалить
});
console.log(obj.name); // Выведет: Alice
// Попытка изменить свойство (будет проигнорирована в строгом режиме или выбросит ошибку)
obj.name = 'Bob';
console.log(obj.name); // Выведет: Alice
// Попытка удалить свойство (будет проигнорирована или выбросит ошибку)
delete obj.name;
console.log(obj.name); // Выведет: Alice
Пример создания свойства с дескриптором аксессоров:
// Создаем объект с приватной переменной
const user = {
_firstName: 'John', // Приватная переменная по соглашению
_lastName: 'Doe'
};
// Определяем свойство 'fullName' с дескриптором аксессоров
Object.defineProperty(user, 'fullName', {
get() {
// Геттер: возвращает полное имя
return `${this._firstName} ${this._lastName}`;
},
set(value) {
// Сеттер: разбивает полное имя на части и обновляет приватные переменные
const parts = value.split(' ');
this._firstName = parts[0];
this._lastName = parts[1];
},
enumerable: true, // Свойство будет перечисляемым
configurable: true // Характеристики свойства можно изменить, свойство можно удалить
});
console.log(user.fullName); // Выведет: John Doe
user.fullName = 'Peter Pan';
console.log(user._firstName); // Выведет: Peter
console.log(user._lastName); // Выведет: Pan
console.log(user.fullName); // Выведет: Peter Pan
Использование дескрипторов позволяет создавать иммутабельные свойства, свойства с ленивым вычислением, свойства с контролем доступа (геттеры/сеттеры) и более гибко управлять поведением объектов.