Значення з полів форми, URL і dataset - завжди рядки. Перетворити їх на число можна кількома способами, і вони поводяться по-різному.
Number(value) і унарний плюс +value - однаково строгі: весь рядок має бути числом.
Number('42'); // 42
Number(' 42 '); // 42 - пробіли по краях ігноруються
Number('42px'); // NaN
Number('3.14'); // 3.14
Number(''); // 0 - пастка!
Number(null); // 0
Number(undefined); // NaN
+'42'; // 42
parseInt(value, radix) читає ціле число з початку рядка й зупиняється на першому недопустимому символі:
parseInt('42px'); // 42
parseInt('3.99'); // 3 - дробова частина відкидається
parseInt('px42'); // NaN
parseInt('ff', 16); // 255
Завжди передавайте основу числення другим аргументом (parseInt(value, 10)) - так намір очевидний, а лінтери цього вимагають.
parseFloat(value) - те саме для дробових: parseFloat('3.14abc') → 3.14.
Що обрати:
- дані з форми, де очікується саме число -
Number(), і перевіряти результат. Він не «пропустить»'12abc'; - значення з одиницями CSS (
'16px') -parseInt/parseFloat; +value- коротко, але менш помітно в коді.
Пастки:
- порожній рядок дає 0, а не
NaN. Порожнє поле «кількість» перетвориться на нуль. Порожнечу треба перевіряти окремо; parseIntз числом, а не рядком:parseInt(0.0000005)→5, бо число спершу перетворюється на рядок'5e-7'. Для округлення чисел єMath.trunc,Math.round;parseIntяк колбекmap:['1', '2', '3'].map(parseInt)дає[1, NaN, NaN], боmapпередає індекс другим аргументом, і він стає основою числення. Правильно:.map(Number)чи.map((s) => parseInt(s, 10));- кома як десятковий роздільник: українські користувачі пишуть
'12,5', аNumber('12,5')- цеNaN. Для введення сум потрібна нормалізація (value.replace(',', '.')) або полеtype="number", значення якого браузер віддає з крапкою.
Перевірка результату: Number.isNaN(n) чи Number.isFinite(n) (відкидає і NaN, і Infinity).