Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що таке гетери й сетери і коли вони доречні?

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

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: ...)).

Докладніше в документації: get

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання