гетер

Синтаксис get прив'язує властивість об'єкта до функції, яка викликатиметься під час звернення до властивості.

Синтаксис

{get prop() { ... } }
{get [expression]() { ... } }

Параметри

prop
Ім'я властивості, яка прив'язується до наданої функції.
expression
Починаючи з ECMAScript 2015, ви також можете використовувати вираз для обчислюваного імені властивості, яка прив'язується до наданої функції.

Опис

Іноді потрібно надати доступ до властивості, яка повертає динамічно обчислюване значення, або ви можете захотіти відобразити статус внутрішньої змінної без потреби використовувати явні виклики методів. У JavaScript це можна здійснити використанням гетера.

Змінна не може одночасно мати прив'язаний гетер та містити значення, але можливо використати гетер в поєднанні з сетером, щоб створити свого роду псевдовластивість.

Пам'ятайте наступне, працюючи з синтаксисом get:

Приклади

Визначення гетерів на нових об'єктах у об'єктних ініціалізаторах

Це створить псевдовластивість latest для об'єкта obj, яка повертатиме останній елемент масиву у log.

const obj = {
  log: ['приклад','тест'],
  get latest() {
    if (this.log.length === 0) return undefined;
    return this.log[this.log.length - 1];
  }
}
console.log(obj.latest); // "тест"

Зауважте, що спроба присвоїти значення latest не змінить її.

Видалення гетера оператором delete

Якщо вам потрібно прибрати гетер, ви можете його просто видалити:

delete obj.latest;

Визначення гетера на існуючому об'єкті за допомогою defineProperty

Щоб додати гетер до існуючого об'єкта пізніше в будь-який момент, використовуйте Object.defineProperty().

const o = {a: 0};

Object.defineProperty(o, 'b', { get: function() { return this.a + 1; } });

console.log(o.b) // Запускає гетер, який вертає a + 1 (тобто 1)

Використання обчислюваного імені властивості

const expr = 'foo';

const obj = {
  get [expr]() { return 'bar'; }
};

console.log(obj.foo); // "bar"

Розумні / самопереписувані / ліниві гетери

Гетери дають можливість визначити властивість об'єкта, але вони не обчислюють значення властивості до звернення. Гетер відкладає вартість обчислення значення, доки значення не знадобиться. Якщо воно ніколи не знадобиться, ви ніколи за це не заплатите.

Додаткова техніка оптимізації, що полягає у відкладені обчислення значення властивості та кешуванні її для пізнішого звернення, створює розумні (або "мемоізовані") гетери. Значення обчислюється під час першого виклику гетера, після чого кешується, а отже, наступні виклики повертають кешоване значення, не переобчислюючи його. Це неймовірно корисно у наступних ситуаціях:

  • Якщо обчислення значення властивості є дорогим (витрачає багато оперативної пам'яті чи часу процесора, створює потоки виконавців, отримує файл, і т.д.).
  • Якщо значення не потрібне вам просто зараз. Воно використовуватиметься пізніше, або в певних випадках не використовуватиметься взагалі.
  • Якщо воно використовується, до нього відбувається декілька звернень, і немає потреби його переобчислювати, значення ніколи не змінюється і не потребує переобчислення.

Це означає, що не варто писати лінивий гетер для властивості, чиє значення ви плануєте змінювати, бо, якщо гетер лінивий, він не буде його переобчислювати.

Зауважте, що гетери не є ані “лінивими”, ані “мемоізованими” від природи; ви маєте реалізувати цю техніку, якщо вам потрібна така поведінка.

У наступному прикладі об'єкт має гетер як особисту властивість. Під час отримання властивості вона видаляється з об'єкта та повторно додається, але цього разу неявно, як властивість-значення. Наприкінці повертається значення.

get notifier() {
  delete this.notifier;
  return this.notifier = document.getElementById('bookmarked-notification-anchor');
},

Для коду Firefox, дивіться також модуль XPCOMUtils.jsm, який визначає функцію defineLazyGetter().

get проти defineProperty

Хоча ключове слово get та метод Object.defineProperty() дають схожі результати, існує тонка різниця між ними при використанні з класами.

При використанні get, властивість буде визначена на прототипі екземпляру, в той час як Object.defineProperty() визначає властивість на екземплярі, до якого застосовується.

class Example {
  get hello() {
    return 'привіт';
  }
}

const obj = new Example();
console.log(obj.hello);
// "привіт"

console.log(Object.getOwnPropertyDescriptor(obj, 'hello'));
// undefined

console.log(
  Object.getOwnPropertyDescriptor(
    Object.getPrototypeOf(obj), 'hello'
  )
);
// { configurable: true, enumerable: false, get: function get hello() { return 'привіт'; }, set: undefined }

Специфікації

Специфікації
ECMAScript (ECMA-262)
The definition of 'Method definitions' in that specification.

Сумісність з веб-переглядачами

BCD tables only load in the browser

Див. також