Использовали ли вы геттеры в Node.js?

Ответ

Да, активно использую геттеры в Node.js для вычисляемых свойств и инкапсуляции логики доступа к данным.

Основные сценарии использования:

  1. Вычисляемые свойства в классах:

    
    class Invoice {
    constructor(items) {
    this.items = items;
    }
    
    get total() {
    return this.items.reduce((sum, item) => sum + item.price * item.quantity, 0);
    }
    
    get tax() {
    return this.total * 0.2; // 20% НДС
    }
    
    get totalWithTax() {
    return this.total + this.tax;
    }
    }

const invoice = new Invoice([ { name: 'Book', price: 10, quantity: 2 }, { name: 'Pen', price: 1, quantity: 5 } ]);

console.log(invoice.total); // 25 console.log(invoice.tax); // 5 console.log(invoice.totalWithTax); // 30


2. **Ленивые вычисления и кэширование:**
```javascript
class UserRepository {
  constructor() {
    this._users = null;
  }

  get users() {
    if (!this._users) {
      // Загружаем только при первом обращении
      this._users = this.loadUsersFromDatabase();
    }
    return this._users;
  }

  async loadUsersFromDatabase() {
    const db = await getDatabaseConnection();
    return db.collection('users').find().toArray();
  }
}
  1. Валидация и преобразование данных:

    class Product {
    constructor(rawData) {
    this.rawData = rawData;
    }
    
    get price() {
    const price = this.rawData.price;
    // Конвертируем центы в доллары
    return price / 100;
    }
    
    get formattedPrice() {
    return `$${this.price.toFixed(2)}`;
    }
    }
  2. Совместно с сеттерами для реактивности:

    class Observable {
    constructor() {
    this._value = 0;
    this.listeners = [];
    }
    
    get value() {
    return this._value;
    }
    
    set value(newValue) {
    const oldValue = this._value;
    this._value = newValue;
    this.listeners.forEach(fn => fn(newValue, oldValue));
    }
    }

В Node.js с ES6+ геттеры работают нативно, без необходимости в Object.defineProperty, что делает код чище и читаемее.

Ответ 18+ 🔞

Ага, ну я тоже эти геттеры в Node.js юзаю, когда надо свойства вычислить или логику доступа спрятать. Честно говоря, иногда это просто спасение, а иногда — ёперный театр с этими геттерами, но в целом штука годная.

Вот где я их обычно впариваю:

  1. Свойства, которые сами считаются, прямо в классах:

    
    class Invoice {
    constructor(items) {
    this.items = items;
    }
    
    get total() {
    // Вот тут просто складываем всё, что накупили
    return this.items.reduce((sum, item) => sum + item.price * item.quantity, 0);
    }
    
    get tax() {
    // НДС, блядь, 20% — куда ж без него
    return this.total * 0.2;
    }
    
    get totalWithTax() {
    // Итог с налогом, чтобы клиент офигел
    return this.total + this.tax;
    }
    }

const invoice = new Invoice([ { name: 'Book', price: 10, quantity: 2 }, { name: 'Pen', price: 1, quantity: 5 } ]);

console.log(invoice.total); // 25 console.log(invoice.tax); // 5 console.log(invoice.totalWithTax); // 30


2. **Ленивая загрузка и кэш, чтобы не дергать базу почём зря:**
```javascript
class UserRepository {
  constructor() {
    this._users = null; // Пока пусто, ёпта
  }

  get users() {
    // Если ещё не грузили — грузим, если уже есть — отдаём как есть
    if (!this._users) {
      this._users = this.loadUsersFromDatabase();
    }
    return this._users;
  }

  async loadUsersFromDatabase() {
    const db = await getDatabaseConnection();
    return db.collection('users').find().toArray();
  }
}
  1. Валидация или преобразование данных, чтобы не париться потом:

    class Product {
    constructor(rawData) {
    this.rawData = rawData;
    }
    
    get price() {
    const price = this.rawData.price;
    // Допустим, в базе цена в центах, а нам надо в долларах
    return price / 100;
    }
    
    get formattedPrice() {
    // Красиво форматируем, чтоб пользователь не охуел от вида "29.999999"
    return `$${this.price.toFixed(2)}`;
    }
    }
  2. Вместе с сеттерами, чтобы всё было реактивно и красиво:

    class Observable {
    constructor() {
    this._value = 0;
    this.listeners = []; // Тут все, кто подписался на изменения
    }
    
    get value() {
    return this._value;
    }
    
    set value(newValue) {
    const oldValue = this._value;
    this._value = newValue;
    // Оповещаем всех, кто ждал этого момента
    this.listeners.forEach(fn => fn(newValue, oldValue));
    }
    }

В Node.js с ES6+ геттеры работают из коробки, не надо городить Object.defineProperty, как в старые добрые времена. Код чище, читается легче — в общем, ебать мои старые костыли, прогресс налицо.