Какой самый чистый и эффективный способ проверки десятичных чисел в JavaScript?
Бонусные баллы за:
- Ясность. Решение должно быть чистым и простым.
- Кросс-платформенный.
Тестовые случаи:
01. IsNumeric('-1') => true
02. IsNumeric('-1.5') => true
03. IsNumeric('0') => true
04. IsNumeric('0.42') => true
05. IsNumeric('.42') => true
06. IsNumeric('99,999') => false
07. IsNumeric('0x89f') => false
08. IsNumeric('#abcdef') => false
09. IsNumeric('1.2.3') => false
10. IsNumeric('') => false
11. IsNumeric('blah') => false
javascript
validation
numbers
Michael Haren
источник
источник
jQuery.isNumeric
функция полезности: api.jquery.com/jQuery.isNumericjQuery.isNumeric
потерпит неудачу в седьмом тестовом примере OP (IsNumeric('0x89f') => *false*
). Однако я не уверен, согласен ли я с этим тестом.Ответы:
Ответ @ Джоэла довольно близок, но не получится в следующих случаях:
Некоторое время назад мне пришлось реализовать
IsNumeric
функцию, чтобы выяснить, содержит ли переменная числовое значение, независимо от ее типа , может ли онаString
содержать числовое значение (я должен был учитывать также экспоненциальную запись и т. Д.),Number
Объект, в эту функцию можно было передать практически все, я не мог делать предположений о типах, принимая во внимание приведение типов (например,+true == 1;
но этоtrue
не следует рассматривать как"numeric"
).Я думаю, стоит поделиться этим набором +30 модульных тестов, сделанных для многочисленных реализаций функций, а также поделиться тем, который проходит все мои тесты:
PS isNaN & isFinite имеют запутанное поведение из-за принудительного преобразования в число. В ES6 Number.isNaN & Number.isFinite исправят эти проблемы. Имейте это в виду при их использовании.
Обновление : вот как jQuery делает это сейчас (2.2-стабильный) :
Обновление : Angular 4.3 :
источник
2e308 > Number.MAX_VALUE
так как2e308 == Infinity
. Если вам нужна функция, которая возвращаетtrue
также положительные и отрицательные значения бесконечности, проверьте функцию № 2 в наборе тестов . Приветствия.Arrrgh! Не слушайте ответы на регулярные выражения. RegEx неприглядно для этого, и я говорю не просто о производительности. Это так легко сделать незаметно, невозможно обнаружить ошибки с помощью регулярного выражения.
Если вы не можете использовать
isNaN()
, это должно работать намного лучше:Вот как это работает:
(input - 0)
Выражение заставляет JavaScript делать тип принуждение от входного значения; сначала его нужно интерпретировать как число для операции вычитания. Если это преобразование в число не удастся, выражение приведет кNaN
. Этот числовой результат затем сравнивается с исходным значением, которое вы передали. Поскольку левая часть теперь числовая, снова используется приведение типа. Теперь, когда ввод с обеих сторон был приведен к одному и тому же типу из одного и того же исходного значения, вы могли бы подумать, что они всегда должны быть одинаковыми (всегда истинными). Однако есть специальное правило, которое говорит, чтоNaN
никогда не равноNaN
, и поэтому значение, которое нельзя преобразовать в число (и только значения, которые нельзя преобразовать в числа), приведет к значению false.Проверка длины предназначена для особого случая, включающего пустые строки. Также обратите внимание, что он не подходит для теста 0x89f, но это потому, что во многих средах это хороший способ определить числовой литерал. Если вы хотите поймать этот конкретный сценарий, вы можете добавить дополнительную проверку. Еще лучше, если это ваша причина не использовать, а
isNaN()
затем просто оберните свою собственную функцию,isNaN()
которая также может выполнить дополнительную проверку.Таким образом, если вы хотите узнать, можно ли преобразовать значение в число, на самом деле попробуйте преобразовать его в число.
Я вернулся и провел некоторое исследование, чтобы выяснить, почему у строки пробелов не было ожидаемого результата, и я думаю, что получил его сейчас:
0
вместо пустой приведена пустая строкаNaN
. Просто обрежьте строку, прежде чем проверка длины будет обрабатывать этот случай.Запуск модульных тестов для нового кода, и он завершается с ошибкой только для бесконечных и логических литералов, и единственное время, которое должно быть проблемой, - это если вы генерируете код (действительно, кто будет вводить литерал и проверять, является ли он числовым? Вы должны знать ), и это будет странный код для генерации.
Но, опять же, единственная причина когда-либо использовать это, если по какой-то причине вам следует избегать isNaN ().
источник
IsNumeric(' ')
,IsNumeric('\n\t')
и т. Д. Все возвращаютсяtrue
Number
литералах,IsNumeric(5) == false;
проверяя набор16
тестовых модулей, которые я разместил, эта функция является номером в наборе тестов. stackoverflow.com/questions/18082/…Этот способ, кажется, работает хорошо:
В одну строку:
И проверить это:
Я позаимствовал это регулярное выражение у http://www.codetoad.com/javascript/isnumeric.asp . Объяснение:
источник
Yahoo! Пользовательский интерфейс использует это:
источник
new Number(1)
.Это работает и для чисел типа 0x23.
источник
IsNumeric('')
,IsNumeric(' ')
,IsNumeric(true)
,IsNumeric(false)
,IsNumeric(null)
Вернутьtrue
вместоfalse
.Принятый ответ не прошел ваш тест № 7, и я думаю, это потому, что вы передумали. Так что это ответ на принятый ответ, с которым у меня возникли проблемы.
Во время некоторых проектов мне нужно было проверить некоторые данные и быть как можно более уверенными, что это числовое значение javascript, которое можно использовать в математических операциях.
jQuery и некоторые другие библиотеки javascript уже включают такую функцию, обычно вызываемую
isNumeric
. Существует также сообщение о стековом потоке , которое было широко принято в качестве ответа, та же самая общая процедура, которую используют вышеупомянутые библиотеки.Во-первых, приведенный выше код вернул бы значение true, если аргумент представлял собой массив длиной 1, и этот единственный элемент имел тип, считающийся числовым по приведенной выше логике. На мой взгляд, если это массив, то он не числовой.
Чтобы облегчить эту проблему, я добавил проверку, чтобы дисконтные массивы из логики
Конечно, вы также можете использовать
Array.isArray
JQuery$.isArray
или прототипObject.isArray
вместоObject.prototype.toString.call(n) !== '[object Array]'
Вторая проблема заключалась в том, что строки букв с отрицательным шестнадцатеричным целым числом ("-0xA" -> -10) не считались числовыми. Однако положительные шестнадцатеричные целочисленные литеральные строки («0xA» -> 10) считались числовыми. Мне нужно, чтобы оба были действительными числовыми.
Затем я изменил логику, чтобы принять это во внимание.
Если вы беспокоитесь о создании регулярного выражения при каждом вызове функции, то вы можете переписать его в закрытии, что-то вроде этого
Затем я взял CMS +30 тестовых случаев и клонировал тестирование на jsfiddle, добавил свои дополнительные тестовые примеры и мое вышеописанное решение.
Он не может заменить общепринятый / используемый ответ, но если это больше того, что вы ожидаете получить в результате выполнения функции isNumeric, то, надеюсь, это поможет вам.
РЕДАКТИРОВАТЬ: Как указал Берги , есть другие возможные объекты, которые можно считать числовыми, и было бы лучше, чтобы белый список, чем черный список. Имея это в виду, я бы добавил к критериям.
Я хочу, чтобы моя функция isNumeric учитывала только числа или строки
Имея это в виду, было бы лучше использовать
Проверьте решения
источник
IsNumeric('99,999') => false
Да, встроенный
isNaN(object)
будет намного быстрее, чем любой анализ регулярных выражений, потому что он встроен и скомпилирован, а не интерпретируется на лету.Хотя результаты несколько отличаются от того, что вы ищете ( попробуйте ):
источник
Используйте функцию
isNaN
. Я полагаю, что если вы проверите!isNaN(yourstringhere)
его, он отлично подойдет для любой из этих ситуаций.источник
Начиная с jQuery 1.7, вы можете использовать
jQuery.isNumeric()
:Просто обратите внимание, что в отличие от того, что вы сказали,
0x89f
это действительное число (гекса)источник
Это может быть сделано без RegExp как
источник
Я понимаю, что оригинальный вопрос не упоминал jQuery, но если вы используете jQuery, вы можете сделать:
Просто.
https://api.jquery.com/jQuery.isNumeric/ (по состоянию на jQuery 1.7)
источник
не работает для меня Когда я поставил оповещение и проверил,
input.length
былоundefined
. Я думаю, что нет свойства для проверки целочисленной длины. Так что я сделалРаботало нормально.
источник
Если я не ошибаюсь, это должно соответствовать любому действительному значению числа JavaScript, за исключением констант (
Infinity
,NaN
) и операторов знака+
/-
(потому что они, на самом деле, не являются частью числа, это отдельные операторы):Мне это понадобилось для токенизатора, где отправка числа в JavaScript для оценки не была возможной ... Это определенно не самое короткое из возможных регулярных выражений, но я считаю, что оно улавливает все тонкости синтаксиса чисел в JavaScript.
Действительные числа будут включать:
Неверные номера будут
источник
Единственная проблема, с которой я столкнулся при ответе @ CMS - исключение
NaN
и Infinity, которые являются полезными числами для многих ситуаций. Один из способов проверитьNaN
это - проверить числовые значения, которые не равны между собойNaN != NaN
,! Итак, на самом деле есть 3 теста, с которыми вы хотели бы иметь дело ...Мой isComparableNumber довольно близок к другому элегантному ответу , но обрабатывает шестнадцатеричные и другие строковые представления чисел.
источник
Для меня это лучший способ:
источник
Я хотел бы добавить следующее:
Положительные шестнадцатеричные числа начинаются с,
0x
а отрицательные шестнадцатеричные числа начинаются с-0x
. Положительные октавные числа начинаются с,0
а отрицательные октавные числа начинаются с-0
. Это принимает большинство из того, что уже было упомянуто, но включает шестнадцатеричные и восьмеричные числа, отрицательное научное, Бесконечность и удаленное десятичное научное (4e3.2
недействительно).источник
Я думаю, что функция parseFloat может сделать всю работу здесь. Функция ниже проходит все тесты на этой странице, включая
isNumeric(Infinity) == true
:источник
IsNumeric([3]) == true;
IsNumeric([]) == false;
IsNumeric([3, 4]) == false;
но я думаю, это дело вкуса!Пара тестов для добавления:
Я придумал это:
Решение охватывает:
источник
Целочисленное значение можно проверить с помощью:
Этот способ проще и быстрее! Все тесты проверены!
источник
Вот немного улучшенная версия (вероятно, самый быстрый выход), которую я использую вместо точного варианта jQuery, я действительно не знаю, почему они не используют эту:
Недостатком версии jQuery является то, что если вы передадите строку с начальными числовыми значениями и последними буквами, такими как
"123abc"
the, тоparseFloat | parseInt
вы извлечете числовую дробь и вернете 123, НО, второй защитникisFinite
все равно потерпит неудачу. С унарным+
оператором он умрет на самом первом страже, так как + выбрасывает NaN для таких гибридов :) Небольшая производительность, но я думаю, что сплошная семантическая выгода.источник
Мое решение,
Похоже, работает в любой ситуации, но я могу ошибаться.
источник
?
для{0,1}
и\d
для[0-9]
. Кроме того,+
а затем оборачивая его(?:){0,1}
, вы можете также использовать*
и забыть (не) группы захвата.Я использую более простое решение:
источник
Это должно работать. Некоторые из представленных здесь функций имеют недостатки, и должны быть быстрее, чем любая другая функция здесь.
Разъяснение:
Создайте свою собственную копию, затем преобразуйте число в число с плавающей запятой, затем сравните себя с исходным числом, если оно все еще число (целое или с плавающей запятой), и совпадает с исходным числом, что означает, что это действительно число.
Он работает как с числовыми строками, так и с простыми числами. Не работает с шестнадцатеричными числами.
Предупреждение: используйте на свой страх и риск, без гарантий.
источник
Ни один из ответов не возвращается
false
для пустых строк, исправление для этого ...источник
Чтобы проверить, содержит ли переменная действительное число, а не просто строку, которая выглядит как число,
Number.isFinite(value)
можно использовать.Это часть языка с ES2015
Примеры:
источник
Number.isFinite('0') -> false
Если n является числовым
Number(n)
, вернет числовое значение иtoString()
превратит его обратно в строку. Но если n не числовоеNumber(n)
, вернется,NaN
поэтому он не будет соответствовать оригиналуn
источник
Я понимаю, что на это отвечали много раз, но ниже приведен достойный кандидат, который может быть полезен в некоторых сценариях.
Следует отметить, что предполагается, что «.42» - это НЕ число, а «4.» это НЕ число, поэтому это следует учитывать.
isDecimal
Проходит следующий тест:Идея здесь состоит в том, что каждое число или целое число имеет одно «каноническое» строковое представление, и каждое неканоническое представление должно быть отклонено. Таким образом, мы приводим число и обратно и видим, является ли результат исходной строкой.
Полезны ли эти функции для вас, зависит от варианта использования. Одна особенность заключается в том, что разные строки представляют разные числа (если обе пройдут
isNumber()
тест).Это относится, например, к числам в качестве имен свойств объекта.
источник
knockoutJs Встроенные функции проверки библиотеки
Расширяя его, поле проверяется
1) номер
self.number = ko.observable(numberValue)
.extend ({число: правда}) ;Прецедент
2) цифра
self.number = ko.observable(numberValue)
.extend ({digit: true}) ;Прецедент
3) мин и макс
self.number = ko.observable(numberValue)
.extend ({мин: 5}). удлинение ({макс: 10}) ;Это поле принимает значение только от 5 до 10
Прецедент
источник
Если вам нужно проверить специальный набор десятичных знаков y, вы можете использовать этот простой javascript:
http://codesheet.org/codesheet/x1kI7hAD
Javascript:
источник
isNumeric=(el)=>{return Boolean(parseFloat(el)) && isFinite(el)}
Ничего особенного, но мы можем использовать булев конструктор
источник