← Назад к вопросам

Что такое getter?

1.0 Junior🔥 92 комментариев
#ООП

Комментарии (2)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Getter: методы для получения значений свойств

Getter — это специальный метод, который позволяет получить значение свойства объекта так, как будто это обычное свойство, но при этом можно выполнить любую логику. Getter вызывается при доступе к свойству, выглядит как обычное чтение, но может делать сложные вычисления.

Базовое понимание

Без getter (обычное свойство):

const person = {
  firstName: 'John',
  lastName: 'Doe'
};

console.log(person.firstName); // 'John'

С getter:

const person = {
  firstName: 'John',
  lastName: 'Doe',
  
  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  }
};

console.log(person.fullName); // 'John Doe'
// Выглядит как свойство, но это метод!

Синтаксис Getter

В объектных литералах

const user = {
  _email: 'john@example.com', // приватное "свойство" (по соглашению)
  
  get email() {
    return this._email;
  }
};

console.log(user.email); // 'john@example.com' (вызывает getter)

В классах (ES6)

class User {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
  
  // Getter
  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  }
}

const user = new User('John', 'Doe');
console.log(user.fullName); // 'John Doe' (вызывает getter)

С приватными полями (#)

class BankAccount {
  #balance = 0; // приватное поле
  
  // Getter для защиты доступа
  get balance() {
    return this.#balance;
  }
  
  // Setter (о нем позже)
  set balance(amount) {
    if (amount >= 0) {
      this.#balance = amount;
    } else {
      throw new Error('Balance cannot be negative');
    }
  }
}

const account = new BankAccount();
account.balance = 100; // вызывает setter
console.log(account.balance); // вызывает getter, выводит 100

Примеры использования

1. Вычисляемое свойство

class Rectangle {
  constructor(width, height) {
    this.width = width;
    this.height = height;
  }
  
  get area() {
    return this.width * this.height;
  }
  
  get perimeter() {
    return 2 * (this.width + this.height);
  }
}

const rect = new Rectangle(5, 10);
console.log(rect.area); // 50 (вычисляется при доступе)
console.log(rect.perimeter); // 30

2. Форматирование данных

class Product {
  constructor(name, price) {
    this.name = name;
    this._price = price; // внутреннее хранилище
  }
  
  get price() {
    return this._price.toFixed(2); // форматирование
  }
  
  get displayPrice() {
    return `$${this.price}`; // добавляем символ доллара
  }
}

const product = new Product('Laptop', 999.5555);
console.log(product.displayPrice); // '$999.56'

3. Защита данных (инкапсуляция)

class User {
  constructor(firstName, lastName) {
    this._firstName = firstName;
    this._lastName = lastName;
  }
  
  // Getter для чтения
  get firstName() {
    console.log('Getting firstName...');
    return this._firstName;
  }
  
  // Setter для записи (см. далее)
  set firstName(value) {
    if (value.length === 0) {
      throw new Error('First name cannot be empty');
    }
    console.log('Setting firstName to', value);
    this._firstName = value;
  }
}

const user = new User('John', 'Doe');
console.log(user.firstName); // "Getting firstName... John"
user.firstName = 'Jane'; // "Setting firstName to Jane"
user.firstName = ''; // Error: First name cannot be empty

4. Кэширование результатов

class ExpensiveCalculation {
  constructor(data) {
    this.data = data;
    this._cachedResult = null;
  }
  
  get result() {
    if (this._cachedResult === null) {
      console.log('Выполняю дорогостоящее вычисление...');
      this._cachedResult = this.data.reduce((sum, num) => sum + num, 0) * 2;
    }
    return this._cachedResult;
  }
}

const calc = new ExpensiveCalculation([1, 2, 3, 4, 5]);
console.log(calc.result); // "Выполняю дорогостоящее вычисление..." -> 30
console.log(calc.result); // 30 (из кэша, без вычисления)

5. Валидация при доступе

class Temperature {
  constructor(celsius) {
    this._celsius = celsius;
  }
  
  get celsius() {
    return this._celsius;
  }
  
  get fahrenheit() {
    return (this._celsius * 9/5) + 32;
  }
  
  get kelvin() {
    if (this._celsius < -273.15) {
      throw new Error('Temperature below absolute zero');
    }
    return this._celsius + 273.15;
  }
}

const temp = new Temperature(25);
console.log(temp.celsius); // 25
console.log(temp.fahrenheit); // 77
console.log(temp.kelvin); // 298.15

Getter vs обычный метод

class Score {
  constructor(points) {
    this.points = points;
  }
  
  // Getter
  get doubled() {
    return this.points * 2;
  }
  
  // Обычный метод
  getDoubled() {
    return this.points * 2;
  }
}

const score = new Score(10);

// Getter: выглядит как свойство
console.log(score.doubled); // 20 (без скобок)

// Метод: нужны скобки
console.log(score.getDoubled()); // 20 (со скобками)

Выбор:

  • Используй getter, если операция "дешевая" и читаемость важнее
  • Используй метод, если операция долгая (HTTP запрос, сложные вычисления)

Setter (обратная сторона)

Setter позволяет задавать значение как свойству:

class User {
  constructor(age) {
    this._age = age;
  }
  
  get age() {
    return this._age;
  }
  
  set age(value) {
    if (value < 0 || value > 150) {
      throw new Error('Invalid age');
    }
    this._age = value;
  }
}

const user = new User(25);
console.log(user.age); // 25 (getter)
user.age = 30; // setter
console.log(user.age); // 30
user.age = 200; // Error: Invalid age

Getter в реальном коде (Express.js + TypeORM)

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity('users')
export class User {
  @PrimaryGeneratedColumn('uuid')
  id: string;
  
  @Column()
  firstName: string;
  
  @Column()
  lastName: string;
  
  @Column()
  email: string;
  
  // Getter для полного имени
  get fullName(): string {
    return `${this.firstName} ${this.lastName}`;
  }
  
  // Getter для проверки
  get isEmailValid(): boolean {
    return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(this.email);
  }
}

// В контроллере
const user = await User.findOne(1);
console.log(user.fullName); // использование как свойства
if (user.isEmailValid) {
  // отправить письмо
}

Отличия между getter и обычным методом

АспектGetterМетод
Синтаксисobj.propobj.method()
ЧитаемостьВыглядит как свойствоВыглядит как действие
ПроизводительностьКаждый раз выполняетсяКаждый раз выполняется
ИспользованиеКогда логика простаяКогда логика сложная

Вывод

Getter — это элегантный способ:

  • Инкапсулировать доступ к данным
  • Валидировать при доступе
  • Форматировать значения
  • Кэшировать результаты
  • Сделать код более читаемым

Используй getter, когда нужно получить значение с некоторой логикой, но хочешь, чтобы выглядело как обычное свойство.

Что такое getter? | PrepBro