Как проверить, что первый аргумент является числом в JavaScript?
Что проверяют
Знаете ли вы, что typeof NaN возвращает 'number', и чем глобальные isNaN и isFinite отличаются от методов Number. Сначала стоит уточнить, нужен ли именно тип number или допустимы строки вроде '42' из формы. Следом часто спрашивают, как это типизировать в TypeScript.
Как отвечать
Строгая проверка типа:
const isNumber = (v) => typeof v === 'number' && Number.isFinite(v);Number.isFinite и сам возвращает false для любого не числа, так что typeof здесь ради читаемости. Ключевые отличия:
Number.isFiniteпротивisFinite: глобальная функция сначала приводит аргумент к числу, иisFinite('12')даётtrue, аNumber.isFinite('12')даётfalse;Number.isNaNпротивisNaN: то же самое,isNaN('abc')возвращаетtrue, хотя строка неNaN;- целые:
Number.isIntegerиNumber.isSafeInteger, если значение пойдёт в идентификатор или индекс; BigInt:typeof 10nэто'bigint', проверка на'number'его не пропустит.
Если допустимы строки, parseFloat не подходит: parseFloat('42abc') возвращает 42. Надёжнее Number(s), но с оговорками: Number('') и Number(' ') дают 0, а '0x10' превращается в 16. Поэтому условие такое: строка непустая после trim() и Number.isFinite(Number(s)) истинно.
Про «первый аргумент»: в обычной функции есть arguments[0], в стрелочной arguments нет, там используют (...args). Отличить «не передали» от «передали undefined» можно по arguments.length или args.length.
В TypeScript аннотация x: number в рантайме ничего не проверяет, для данных извне пишут type guard (v: unknown): v is number или валидируют схемой, например на Zod.
Где спотыкаются
Проверяют только typeof, и NaN из неудачного вычисления проходит как число.
Используют глобальный isNaN и получают неверный ответ на строках из-за неявного приведения.
Берут parseFloat для валидации ввода и принимают '42px' за корректное число.