Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

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

Иногда свойство должно не просто хранить значение, а что-то делать: вычислять результат на лету или проверять, что в него записывают. Для этого есть геттеры и сеттеры — методы, которые снаружи выглядят как обычные свойства.

Геттер

Слово get перед методом превращает его в геттер. К нему обращаются как к свойству, без скобок, а возвращает он результат метода:

class User {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
 
  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  }
}
 
const user = new User('Анна', 'Смирнова');
 
console.log(user.fullName); // Анна Смирнова

Вычисляемое значение всегда актуально

Геттер вычисляет значение при каждом обращении, поэтому оно не устаревает, когда меняются исходные данные:

class Cart {
  items = [];
 
  get total() {
    return this.items.reduce((sum, item) => sum + item.price, 0);
  }
}
 
const cart = new Cart();
cart.items.push({ title: 'Чай', price: 5 });
cart.items.push({ title: 'Кофе', price: 12 });
 
console.log(cart.total); // 17

Хранить сумму в отдельном свойстве и не забывать её пересчитывать не нужно.

Сеттер

Слово set объявляет сеттер — метод, который вызывается при записи в свойство. Записанное значение приходит в его параметр:

class User {
  set name(value) {
    this.firstName = value.trim();
  }
}
 
const user = new User();
user.name = '  Олег  ';
 
console.log(user.firstName); // Олег

Проверка значения

Главная польза сеттера — проверка данных. Вместе с приватным полем он не даст записать в объект неверное значение:

class Product {
  #price = 0;
 
  get price() {
    return this.#price;
  }
 
  set price(value) {
    if (value < 0) {
      throw new Error('Цена не может быть отрицательной');
    }
    this.#price = value;
  }
}
 
const product = new Product();
product.price = 25;
 
console.log(product.price); // 25

Запись product.price = -5 выбросила бы ошибку, и неверная цена не попала бы в объект.

Свойство только для чтения

Если объявить геттер без сеттера, свойство можно только читать. Запись в него не срабатывает: в обычном скрипте она молча пропускается, а в модулях и строгом режиме вызывает ошибку TypeError:

class Circle {
  constructor(radius) {
    this.radius = radius;
  }
 
  get diameter() {
    return this.radius * 2;
  }
}
 
const circle = new Circle(5);
circle.diameter = 100;
 
console.log(circle.diameter); // 10

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

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

class User {
  set name(value) {
    this.name = value; // сеттер вызывает сам себя бесконечно
  }
}

Значение храните в поле с другим именем — обычно в приватном: this.#name = value.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.