Ответ
Да, активно использую геттеры в Node.js для вычисляемых свойств и инкапсуляции логики доступа к данным.
Основные сценарии использования:
-
Вычисляемые свойства в классах:
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();
}
}
-
Валидация и преобразование данных:
class Product { constructor(rawData) { this.rawData = rawData; } get price() { const price = this.rawData.price; // Конвертируем центы в доллары return price / 100; } get formattedPrice() { return `$${this.price.toFixed(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 юзаю, когда надо свойства вычислить или логику доступа спрятать. Честно говоря, иногда это просто спасение, а иногда — ёперный театр с этими геттерами, но в целом штука годная.
Вот где я их обычно впариваю:
-
Свойства, которые сами считаются, прямо в классах:
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();
}
}
-
Валидация или преобразование данных, чтобы не париться потом:
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)}`; } } -
Вместе с сеттерами, чтобы всё было реактивно и красиво:
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, как в старые добрые времена. Код чище, читается легче — в общем, ебать мои старые костыли, прогресс налицо.