Дескриптори властивостей.
Фронтенд розробка JavaScript. -> Дескриптори властивостей.
Дескриптори властивостей.
Ми розглянемо можливості, які дозволяють дуже гнучко та потужно керувати всіма властивостями об’єкта, включаючи їх аспекти – змінність, видимість у циклі for..in та навіть непомітно виконувати їх функціями.
Основний метод управління властивостями – Object.defineProperty.
Він дозволяє оголосити властивість об’єкта і, що найголовніше, тонко налаштувати його особливі аспекти, які ніяк не змінити інакше.
Синтаксис:
Object.defineProperty(obj, prop, descriptor)
obj - Об’єкт, у якому оголошується властивість.
prop - Ім’я властивості, яку потрібно оголосити чи модифікувати.
descriptor - Дескриптор – об’єкт, який визначає поведінка якості.
У ньому можуть бути такі поля:
value – writable – значення якості можна змінювати, якщо true. За промовчанням false.
configurable – якщо true, то властивість можна видаляти, а також змінювати її надалі за допомогою нових викликів defineProperty. За промовчанням false.
enumerable – якщо true, то властивість проглядається у циклі for..in та методі Object.keys(). За промовчанням false.
get – функція, яка повертає значення якості. За замовчуванням undefined.
set – функція, яка записує значення якості. За замовчуванням undefined.
Щоб уникнути конфлікту, заборонено одночасно вказувати значення значення та функції get/set.
Звичайна властивість
var user = {};
// 1. Просте присвоєння
user.name = "Вася";
// 2. вказівка значення через дескриптор
Object.defineProperty(user, "name", { value: "Вася", configurable: true, writable: true, enumerable: true });
Для того, щоб зробити властивість незмінною, змінимо її прапори writable і configurable:
"use strict";
var user = {};
Object.defineProperty(user, "name", {
value: "Вася",
writable: false, // заборонити присвоєння "user.name="
configurable: false // заборонити видалення "delete user.name"
});
// Тепер спробуємо змінити цю властивість.
// в strict mode присвоение "user.name=" викличе помилку
user.name = "Петя";
Властивість-функція Дескриптор дозволяє встановити властивість, яка насправді працює як функція. Для цього в ньому потрібно вказати цю функцію get.
var user = {
firstName: "Вася",
surname: "Петров"
}
Object.defineProperty(user, "fullName", {
get: function() {
return this.firstName + ' ' + this.surname;
}
});
alert(user.fullName); // Вася Петров
Також можна вказати функцію, яка використовується для запису значення за допомогою дескриптора set.
var user = {
firstName: "Вася",
surname: "Петров"
}
Object.defineProperty(user, "fullName", {
get: function() {
return this.firstName + ' ' + this.surname;
},
set: function(value) {
var split = value.split(' ');
this.firstName = split[0];
this.surname = split[1];
}
});
user.fullName = "Петя Иванов";
alert( user.firstName ); // Петя
alert( user.surname ); // Иванов
Вказівка get/set у літералах
Якщо ми створюємо об’єкт за допомогою синтаксису { … }, то задати властивості-функції можна у його визначенні.
Для цього використовується спеціальний синтаксис: get властивість або set властивість.
var user = {
firstName: "Вася",
surname: "Петров",
get fullName() {
return this.firstName + ' ' + this.surname;
},
set fullName(value) {
var split = value.split(' ');
this.firstName = split[0];
this.surname = split[1];
}
};
alert( user.fullName ); // Вася Петров (з геттера)
user.fullName = "Петя Іванов";
alert(user.firstName); // Петя (поставив сетер)
alert(user.surname); // Іванов (поставив сетер)