Перейти к содержимому
Теория · Классы и прототипы · урок 2 из 12

Геттеры и сеттеры

В прошлом уроке класс задавал свойства один раз, в constructor. Но некоторые значения зависят от других. Представьте записку на холодильнике: «до конца стирки 2 минуты». Через минуту записка уже врёт. Часы на стиральной машине так не ошибаются: они пересчитывают время каждый раз, когда вы на них смотрите.

Свойство, посчитанное в constructor, похоже на записку: оно запоминает значение один раз. Если потом изменить данные, из которых его получили, оно устареет:

JavaScript
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.

Геттер и сеттер

Чтобы свойство работало как часы, а не как записка, в класс пишут геттер и сеттер. Вот тот же таймер, переписанный с ними:

JavaScript
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(), и он может принимать аргументы.

Геттер подходит для значения, которое выводится из данных объекта: минуты из секунд, площадь из сторон. Для действия или для расчёта с параметрами пишут обычный метод.

Частая ошибка

Геттер вызвали со скобками, как обычный метод:

JavaScript
const timer = new Timer();
console.log(timer.minutes()); // ✗
TEXT
TypeError: timer.minutes is not a function

Выражение timer.minutes уже запустило геттер и дало число 0. Скобки после него пытаются вызвать это число как функцию. Геттер читают без скобок: timer.minutes.

Главное

  • Геттер get пересчитывает значение при каждом чтении, и его читают без скобок.
  • Сеттер set срабатывает, когда свойству присваивают значение, и получает его в параметре.
  • Само значение хранится в других свойствах объекта, а геттер и сеттер только читают и меняют их.

Подпишись, чтобы пройти курс

Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.

Войти другим способом