Геттеры и сеттеры
В прошлом уроке класс задавал свойства один раз, в constructor. Но некоторые значения зависят от других. Представьте записку на холодильнике: «до конца стирки 2 минуты». Через минуту записка уже врёт. Часы на стиральной машине так не ошибаются: они пересчитывают время каждый раз, когда вы на них смотрите.
Свойство, посчитанное в constructor, похоже на записку: оно запоминает значение один раз. Если потом изменить данные, из которых его получили, оно устареет:
class Timer {
constructor(seconds) {
this.seconds = seconds;
this.minutes = seconds / 60;
}
}
const t = new Timer(120);
t.seconds = 300;
console.log(t.minutes); // 2Свойство minutes посчитали при создании объекта, когда секунд было 120. Новое значение seconds на него уже не влияет, и программа печатает устаревшее 2 вместо 5.
Геттер и сеттер
Чтобы свойство работало как часы, а не как записка, в класс пишут геттер и сеттер. Вот тот же таймер, переписанный с ними:
class Timer {
seconds = 0;
get minutes() {
return this.seconds / 60;
}
set minutes(value) {
this.seconds = value * 60;
}
}
const t = new Timer();
t.seconds = 300;
console.log(t.minutes); // 5
t.minutes = 2;
console.log(t.seconds); // 120Геттер
Геттер — метод, перед которым стоит слово get. Снаружи он выглядит как обычное свойство: его читают без скобок, t.minutes. При каждом чтении геттер выполняется заново и берёт текущие данные объекта. Параметров у геттера нет, а значение он отдаёт через return.
Геттер minutes хранит не число, а правило: поделить seconds на 60. Поэтому после t.seconds = 300 чтение t.minutes даёт 5.
Сеттер
Сеттер — метод со словом set и одним параметром. Он срабатывает, когда свойству с тем же именем присваивают значение: t.minutes = 2 вызывает сеттер, и параметр value равен 2.
Сеттер minutes делает обратное геттеру и записывает в seconds число 120. Само свойство minutes нигде не хранится: и чтение, и запись идут через seconds.
Сеттер похож на кнопку настройки часов: вы задаёте нужное время, а часы сами меняют то, что у них внутри. Здесь сравнение и кончается. Часы идут и без вас, а геттер ничего не считает, пока свойство не прочитают.
Геттер или метод
На собеседовании спрашивают, чем геттер отличается от обычного метода. Оба — функции внутри класса, разница в том, как их запускают:
- геттер запускается при чтении свойства,
t.minutes, без скобок и без аргументов; - метод вызывают со скобками, как
ann.isAdult(), и он может принимать аргументы.
Геттер подходит для значения, которое выводится из данных объекта: минуты из секунд, площадь из сторон. Для действия или для расчёта с параметрами пишут обычный метод.
Частая ошибка
Геттер вызвали со скобками, как обычный метод:
const timer = new Timer();
console.log(timer.minutes()); // ✗TypeError: timer.minutes is not a functionВыражение timer.minutes уже запустило геттер и дало число 0. Скобки после него пытаются вызвать это число как функцию. Геттер читают без скобок: timer.minutes.
Главное
- Геттер
getпересчитывает значение при каждом чтении, и его читают без скобок. - Сеттер
setсрабатывает, когда свойству присваивают значение, и получает его в параметре. - Само значение хранится в других свойствах объекта, а геттер и сеттер только читают и меняют их.
Подпишись, чтобы пройти курс
Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.