Ревью: расчёт суммы заказа
Вопрос
Перед тобой код на ревью. Скажи вслух, что здесь не так - по убыванию важности.
Читай вслух, как на ревью: сначала что делает код, потом что сломано.
function total(items, discountPercent) {
let sum = 0;
for (let i = 0; i < items.length; i++) {
sum += items[i].price * items[i].qty;
}
const discounted = sum - (sum * discountPercent) / 100;
return discounted.toFixed(2);
}
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
деньги в числах с плавающей точкой дают ошибку округления
хранить и считать надо в копейках целыми числами
toFixed возвращает строку - дальше её сложат как строку
toFixed округляет не по правилам банковского округления и врёт на границе
нет проверки на отсутствующие price и qty
нет ограничения discountPercent диапазоном 0..100
Что могут спросить следом
- Как бы вы считали НДС в этой же функции?
- Где выполнять расчёт - на клиенте или на сервере?
Разбор
Плавающая точка и деньги. 0.1 + 0.2 даёт 0.30000000000000004; на большом чеке
это превращается в расхождение с бухгалтерией на копейки, которое потом ищут неделю.
Правильно - хранить и считать в минимальных единицах (копейках) целыми числами, а делить
только при выводе.
toFixed возвращает строку. Если результат пойдёт дальше в сложение, получится
конкатенация: "100.00" + 50 = "100.0050". Функция расчёта должна возвращать число,
форматирование - отдельно.
Округление. toFixed округляет по представлению двоичного числа, а не по правилам:
(1.005).toFixed(2) даёт "1.00". Для денег нужно явное правило округления, согласованное
с бэкендом.
Входные данные. Нет ни проверки на undefined в price/qty (получим NaN, который
разойдётся по всему расчёту), ни ограничения скидки диапазоном - отрицательный процент
увеличит сумму.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Предыдущий вопрос
Ревью: мемоизация, которая не работает
Следующий вопрос
Ревью: большой список с фильтром