Дескриптори властивостей.

Фронтенд розробка JavaScript. -> Дескриптори властивостей.

Дескриптори властивостей.

Ми розглянемо можливості, які дозволяють дуже гнучко та потужно керувати всіма властивостями об’єкта, включаючи їх аспекти – змінність, видимість у циклі for..in та навіть непомітно виконувати їх функціями.

Основний метод управління властивостями – Object.defineProperty.

Він дозволяє оголосити властивість об’єкта і, що найголовніше, тонко налаштувати його особливі аспекти, які ніяк не змінити інакше.

Синтаксис:

Object.defineProperty(obj, prop, descriptor)

obj - Об’єкт, у якому оголошується властивість.

prop - Ім’я властивості, яку потрібно оголосити чи модифікувати.

descriptor - Дескриптор – об’єкт, який визначає поведінка якості.

У ньому можуть бути такі поля:

valuewritable – значення якості можна змінювати, якщо 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); // Іванов (поставив сетер)