Гетер - метод, який викликається при читанні властивості. Сетер - при записі. Ззовні це виглядає як звичайна властивість, без дужок.
class Temperature {
#celsius = 0;
get fahrenheit() {
return this.#celsius * 9 / 5 + 32;
}
set fahrenheit(value) {
this.#celsius = (value - 32) * 5 / 9;
}
get celsius() {
return this.#celsius;
}
set celsius(value) {
if (value < -273.15) throw new RangeError('Нижче абсолютного нуля');
this.#celsius = value;
}
}
const t = new Temperature();
t.celsius = 25;
t.fahrenheit; // 77
t.fahrenheit = 32;
t.celsius; // 0
У об'єктних літералах так само:
const user = {
first: 'Оля',
last: 'Коваль',
get fullName() { return `${this.first} ${this.last}`; },
};
Де доречні:
- обчислювані властивості - значення, що виводиться з інших (
fullName,total,isEmpty); - валідація при записі - сетер відкидає некоректні значення;
- зворотна сумісність - була звичайна властивість, стала обчислюваною, а код, що її використовує, не змінився;
- властивість лише для читання - гетер без сетера.
Підводні камені:
- гетер без сетера - запис мовчки ігнорується в нестрогому режимі й кидає
TypeErrorу строгому (модулі й класи завжди строгі); - дорогий гетер виглядає як дешеве поле.
list.totalу циклі на тисячу ітерацій, що щоразу перераховує суму, - прихована проблема продуктивності. Важкі обчислення краще робити явним методом чи кешувати; - побічні ефекти в гетері - погана практика: читання властивості не повинно нічого змінювати;
- рекурсія: сетер
set name(v) { this.name = v; }викличе сам себе нескінченно - зберігати значення треба в іншому полі (#name); - серіалізація:
JSON.stringifyвикликає гетери власних властивостей об'єкта-літерала, але гетери класу живуть у прототипі й не потрапляють у JSON. Для класу потрібенtoJSON().
Низькорівнево гетери й сетери - це дескриптори властивостей: Object.defineProperty(obj, 'x', { get() {...}, set(v) {...} }). Саме так працювала реактивність Vue 2 - кожна властивість даних перетворювалася на пару гетер/сетер, що відстежувала читання й записи.
У Vue 3 аналог - computed, у Laravel - аксесори й мутатори моделі (Attribute::make(get: ..., set: ...)).