Ответ вслух Middle Код-ревью спрашивают часто обновлено

Ревью: расчёт суммы заказа

Вопрос

Перед тобой код на ревью. Скажи вслух, что здесь не так - по убыванию важности.

Читай вслух, как на ревью: сначала что делает код, потом что сломано.

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 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Плавающая точка и деньги. 0.1 + 0.2 даёт 0.30000000000000004; на большом чеке это превращается в расхождение с бухгалтерией на копейки, которое потом ищут неделю.

Что должно прозвучать в ответе

  • деньги в числах с плавающей точкой дают ошибку округления

  • хранить и считать надо в копейках целыми числами

  • 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 ошибок.