гетер

Синтаксис 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.

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

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
getChrome Full support 1Edge Full support 12Firefox Full support 1.5IE Full support 9Opera Full support 9.5Safari Full support 3WebView Android Full support 1Chrome Android Full support 18Firefox Android Full support 4Opera Android Full support 14Safari iOS Full support 1Samsung Internet Android Full support 1.0nodejs Full support Yes
Computed property namesChrome Full support 46Edge Full support 12Firefox Full support 34IE No support NoOpera Full support 47Safari Full support 9.1WebView Android Full support 46Chrome Android Full support 46Firefox Android Full support 34Opera Android Full support 33Safari iOS Full support 9.3Samsung Internet Android Full support 5.0nodejs Full support Yes

Legend

Full support  
Full support
No support  
No support

Див. також