Геттеры и сеттеры
Представьте свойство объекта, которое выглядит как обычное поле — но при чтении вычисляется, а при записи проверяет значение. Это геттеры и сеттеры — мощный инструмент для создания «умных» свойств с валидацией и вычислениями на лету.
🤔 Зачем нужны геттеры?
Допустим, у нас есть объект пользователя с именем и фамилией:
const user = {
firstName: "Иван",
lastName: "Петров"
};
Часто нам нужно полное имя — "Иван Петров". Можно написать метод:
const user = {
firstName: "Иван",
lastName: "Петров",
getFullName() {
return this.firstName + " " + this.lastName;
}
};
console.log(user.getFullName()); // Иван Петров
Работает! Но есть маленькая неудобность — нужно вызывать метод со скобками: user.getFullName(). Это нарушает интуицию: мы же хотим читать свойство, а не вызывать функцию.
Геттер решает именно эту проблему: он выглядит как обычное свойство, но внутри — функция.
🎯 Геттер (get) — это метод, который вызывается автоматически, когда вы читаете свойство. Снаружи выглядит как поле, внутри — функция.
✍️ Синтаксис геттера: ключевое слово get
Перепишем пример выше с геттером:
const user = {
firstName: "Иван",
lastName: "Петров",
get fullName() { // геттер — ключевое слово get
return this.firstName + " " + this.lastName;
}
};
// Обращаемся как к обычному свойству — БЕЗ скобок!
console.log(user.fullName); // Иван Петров
Заметьте разницу: теперь мы пишем user.fullName без скобок — как будто это обычное поле. Но на самом деле JavaScript видит слово get и знает: при обращении к этому свойству нужно вызвать функцию и вернуть её результат.
user.getFullName()
// Иван Петров
user.fullName
// Иван Петров
Геттер — это «умное» свойство, только для чтения. Попробуйте присвоить ему значение без сеттера — и ничего не произойдёт (в строгом режиме будет ошибка).
🔒 Сеттер: перехватываем присваивание
Сеттер — это противоположность геттера. Он вызывается, когда вы присваиваете значение свойству.
🎯 Сеттер (set) — это метод, который вызывается автоматически, когда вы присваиваете значение свойству. Позволяет валидировать данные или делать побочные действия при изменении.
Классический пример — объект пользователя, где полное имя можно и читать, и задать одной строкой:
const user = {
firstName: "Иван",
lastName: "Петров",
get fullName() {
return this.firstName + " " + this.lastName;
},
set fullName(value) { // сеттер — ключевое слово set
const parts = value.split(" "); // разбиваем строку по пробелу
this.firstName = parts[0]; // первое слово → имя
this.lastName = parts[1] || ""; // второе слово → фамилия
}
};
console.log(user.fullName); // Иван Петров
user.fullName = "Мария Сидорова"; // вызывается сеттер
console.log(user.firstName); // Мария
console.log(user.lastName); // Сидорова
console.log(user.fullName); // Мария Сидорова
Разберём строку set fullName(value): сеттер всегда принимает ровно один аргумент — новое значение, которое пытаются присвоить. Внутри мы решаем, что с этим значением делать: разбиваем строку, валидируем, обновляем другие свойства.
🛡️ Главная сила сеттеров — валидация
Самое полезное применение сеттеров — это проверка данных перед сохранением. Без сеттера ничто не мешает задать отрицательный возраст или пустое имя. С сеттером — мы контролируем каждое присваивание:
const person = {
_age: 0, // нижнее подчёркивание — условное соглашение
// "это внутреннее поле, не трогай напрямую"
get age() {
return this._age;
},
set age(value) {
if (typeof value !== "number") {
console.log("Возраст должен быть числом!");
return;
}
if (value < 0 || value > 150) {
console.log("Некорректный возраст: " + value);
return;
}
this._age = value; // всё проверено — сохраняем
}
};
person.age = 25; // OK
console.log(person.age); // 25
person.age = -5; // Некорректный возраст: -5
console.log(person.age); // 25 (не изменился)
person.age = "много"; // Возраст должен быть числом!
console.log(person.age); // 25 (не изменился)
Обратите внимание на _age (с нижним подчёркиванием). Это негласное соглашение в JavaScript: подчёркивание означает «внутреннее поле, не рекомендуется использовать снаружи». Снаружи работаем через person.age (геттер/сеттер), внутри храним в _age.
⚠️ Нельзя называть геттер и внутреннее поле одинаково: get age() и age: 0 одновременно — это вызовет бесконечную рекурсию. Поэтому используется _age для хранения и age для доступа.
⚙️ Вычисляемые свойства: геттер для возраста
Другое отличное применение геттеров — вычисляемые свойства, которые автоматически обновляются. Вместо того чтобы хранить возраст (который нужно каждый год обновлять), можно хранить дату рождения и вычислять возраст на лету:
const person = {
name: "Анна",
birthYear: 1998,
get age() {
const currentYear = new Date().getFullYear();
return currentYear - this.birthYear;
}
};
console.log(person.name); // Анна
console.log(person.age); // 27 (вычисляется автоматически!)
Каждый раз при обращении к person.age геттер вызывает new Date().getFullYear() и вычисляет актуальный возраст. Не нужно обновлять поле каждый год — данные всегда свежие.
❌ Нужно обновлять каждый год. Можно забыть. Устаревает.
✅ Всегда актуально. Вычисляется в момент обращения.
🏫 Геттеры и сеттеры в классе
Классы мы разберём в следующем уроке, но геттеры и сеттеры там работают точно так же — только синтаксически они находятся внутри блока class. Вот предварительный взгляд:
class User {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
set fullName(value) {
[this.firstName, this.lastName] = value.split(" ");
}
}
const u = new User("Пётр", "Иванов");
console.log(u.fullName); // Пётр Иванов
u.fullName = "Сергей Смирнов";
console.log(u.firstName); // Сергей
Синтаксис идентичен — get и set перед именем метода. Разница только в том, что это внутри class {...}.
🎯 Когда использовать геттеры и сеттеры
✅ Используй геттер, когда:
- Свойство вычисляется из других свойств (
fullNameизfirstName + lastName) - Значение должно быть всегда актуальным (возраст из даты рождения)
- Хочешь, чтобы свойство выглядело как поле, но вело себя как функция
✅ Используй сеттер, когда:
- Нужна валидация при установке значения (проверить тип, диапазон, формат)
- Присваивание одного свойства должно обновить несколько других
- Нужно сделать побочные действия при изменении (логирование, уведомления)
❌ Не используй, когда:
- Свойство простое — просто храни значение в обычном поле
- Вычисление очень тяжёлое — лучше кешировать результат в методе
- Логика слишком сложная — выноси в обычные методы с говорящими именами
✅ Итоги урока
- Геттер (
get) — метод, вызываемый при чтении свойства. Выглядит как поле, работает как функция - Сеттер (
set) — метод, вызываемый при присваивании значения. Принимает один аргумент — новое значение - Синтаксис:
get propName() {}иset propName(value) {}— в объектном литерале или в классе - Геттеры отлично подходят для вычисляемых свойств:
fullName,age,total - Сеттеры — для валидации: проверяй данные перед сохранением, отклоняй некорректные
- Внутреннее поле хранят с
_:_age, снаружи доступ через геттер/сеттерage - В классах синтаксис геттеров и сеттеров идентичен — те же слова
getиset
В следующем уроке — классы: синтаксис class, конструктор, методы, статические поля и приватные свойства. 🚀
Геттеры и сеттеры
6 вопросов