Какво знаеш за дескрипторите?
sobes.tech AI
Отговор от AI
Дескрипторите в JavaScript са обекти, които описват различни свойства на обект, като стойността му (value), възможността за писане (writable), възможността за обхождане (enumerable) и възможността за конфигуриране (configurable). Има също дескриптори с гетъри и сетъри.
Има два типа дескриптори:
-
Данни дескриптори: съдържат стойността на свойството.
value: Стойността на свойството. Може да бъде всеки валиден тип данни.writable: Логическа стойност. Ако еtrue, стойността на свойството може да бъде променена (obj.prop = newValue). По подразбиранеfalseза accessor свойства иtrueза данни, създадени с обикновено присвояване.enumerable: Логическа стойност. Ако еtrue, свойството ще бъде видимо при итерация през свойствата на обекта (например, в цикълfor...inили сObject.keys()). По подразбиранеfalseза свойства, добавени сObject.defineProperty, иtrueза свойства, създадени с обикновено присвояване.configurable: Логическа стойност. Ако еtrue, характеристиките на дескриптора (освенvalueиwritable, когато се променят от данни към accessor) могат да бъдат променяни, а свойството да бъде изтрито. По подразбиранеfalseза свойства, добавени сObject.defineProperty(освенvalue), иtrueза свойства, създадени с обикновено присвояване. След като е конфигурирано като не-конфигурируемо, не може да бъде променяно обратно. Можете да намалитеwritableотtrueнаfalse, но не и обратното за не-конфигурируем getter/setter.
-
Accessor дескриптори: Определят функции, които ще бъдат извиквани при получаване (getter) или задаване (setter) на стойността на свойството.
get: Функция, която се извиква при четене на свойството. Резултатът от тази функция става стойността на свойството. Не приема аргументи.set: Функция, която се извиква при запис в свойството. Приема един аргумент — новата зададена стойност.enumerable: Логическа стойност (аналогично на data-дескрипторите).configurable: Логическа стойност (аналогично на data-дескрипторите).
Дескрипторите не могат да се смесват: свойството има или value и writable, или get и set.
Дескрипторите се използват за управление на свойствата на обекта на по-ниско ниво, отколкото обикновеното присвояване, по-специално чрез методи като Object.defineProperty(), Object.defineProperties(), Object.getOwnPropertyDescriptor(), Object.getOwnPropertyDescriptors(), Object.create().
Пример за създаване на свойство с data-дескриптор:
// Създаваме празен обект
const obj = {};
// Определяме свойството 'name' с data-дескриптор
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
Пример за създаване на свойство с accessor-дескриптор:
// Създаваме обект с частна променлива
const user = {
_firstName: 'John', // Конвенционална частна променлива
_lastName: 'Doe'
};
// Определяме свойството 'fullName' с accessor-дескриптор
Object.defineProperty(user, 'fullName', {
get() {
// Getter: връща пълното име
return `${this._firstName} ${this._lastName}`;
},
set(value) {
// Setter: разделя пълното име на части и актуализира частните променливи
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
Използването на дескриптори позволява създаването на неизменяеми свойства, свойства с лениво изчисление, свойства с контрол на достъпа (getter/setter) и по-гъвкаво управление на поведението на обектите.