Геттеры и сеттеры в JS — зачем они и когда использовать?
Встретил в чужом коде get и set внутри объекта и не понял, что это. Выглядит как свойство, но с телом функции.
Что такое геттеры и сеттеры js, чем они отличаются от обычных методов и зачем вообще нужны, если можно просто завести свойство? И при чём тут Object.defineProperty?
2 ответа
Геттер и сеттер — это «свойства-функции». Снаружи они выглядят как обычное свойство (без скобок), но при чтении/записи под капотом вызывается функция. Это даёт возможность встроить логику в момент доступа.
Простой пример:
const user = {
firstName: 'Иван',
lastName: 'Петров',
get fullName() {
return `${this.firstName} ${this.lastName}`;
},
set fullName(value) {
[this.firstName, this.lastName] = value.split(' ');
}
};
console.log(user.fullName); // 'Иван Петров' — сработал get
user.fullName = 'Анна Смирнова'; // сработал set
console.log(user.firstName); // 'Анна'
Обрати внимание: user.fullName — без скобок! В этом и суть: пользуешься как обычным свойством, а логика всё равно отрабатывает.
Зачем это нужно:
- вычисляемые значения (как
fullNameвыше); - валидация при записи (например, не дать поставить отрицательный возраст);
- скрыть внутреннее хранение.
Через Object.defineProperty то же самое можно задать программно, уже после создания объекта:
Object.defineProperty(user, 'age', {
get() { return this._age; },
set(v) {
if (v < 0) throw new Error('Возраст не может быть отрицательным');
this._age = v;
}
});
На практике геттеры/сеттеры чаще пишут в классах — там синтаксис ровно такой же (get/set перед именем метода).
Главное правило: не пихай в геттер тяжёлые вычисления или запросы. Снаружи это выглядит как простое чтение свойства, и человек не ожидает, что obj.value вдруг полезет в сеть или будет считать что-то долгое.
Геттер должен быть быстрым и предсказуемым. Если логика дорогая — лучше сделать честный метод getValue() со скобками, чтобы было видно: тут происходит работа.