Построить цепочечный калькулятор с приватным значением только для чтения
Реализуйте createCalculator(), возвращающую объект с поддержкой цепочек: createCalculator().add(7).div(2) оставляет значение 3.5, читаемое через .value. Требования: value доступно только для чтения снаружи (присваивание ему не должно менять накопленную сумму); div(0) бросает Error('Cannot divide by zero') и НЕ должен менять значение.
function createCalculator() {
// ваш код здесь
}
Допишите реализацию.
Хранить накопленную сумму в переменной замыкания. Вернуть объект, чьи add/div меняют её и делают return this для цепочки. Открыть сумму только через аксессор get value() — без сеттера calc.value = 100 молча игнорируется, поэтому состояние остаётся приватным. В div проверить делитель и сделать throw до деления, чтобы деление на ноль не тронуло сумму.
- ✗Открывать сумму как записываемое свойство вместо геттера, из-за чего внешний код может её испортить
- ✗Делить до проверки на ноль, из-за чего
div(0)меняет значение (наInfinity/NaN) до исключения - ✗Возвращать число из
add/divвместоthis, ломая цепочку
- →Как
valueтолько с геттером сохраняет сумму приватной по сравнению с публичным полем? - →Как приватные поля
#класса дали бы ту же инкапсуляцию, что и переменная замыкания?
Решение
Сумма живёт в переменной замыкания; методы меняют её и возвращают this, а value — только геттер.
function createCalculator() {
let total = 0;
return {
get value() {
return total;
},
add(x) {
total += x;
return this;
},
div(x) {
if (x === 0) throw new Error('Cannot divide by zero');
total /= x;
return this;
},
};
}
createCalculator().add(7).div(2).value; // 3.5
Как это работает
total объявлена в createCalculator и недоступна снаружи — это и есть приватное состояние через замыкание. Наружу она отдаётся лишь геттером value без сеттера: попытка calc.value = 100 молча проигнорируется (или бросит ошибку в строгом режиме), и сумму не испортить.
add и div меняют total и возвращают this, благодаря чему вызовы складываются в цепочку. В div проверка делителя стоит до деления: при нуле метод бросает исключение и до строки total /= x не доходит, поэтому значение остаётся прежним.