Какой самый чистый и эффективный способ проверки десятичных чисел в 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
Десятичная запятая является стандартом во всей Европе и России (кроме Великобритании).
Также проверьте этот пост и отличные комментарии.
jQuery 1.7 представил служебную функцию jQuery.isNumeric: api.jquery.com/jQuery.isNumeric
jQuery.isNumeric не пройдет седьмой тестовый пример OP (IsNumeric('0x89f') => *false*). Однако я не уверен, согласен ли я с этим тестовым примером.
функция isnum (число) {return res = (число / число)? истина: ложь; }
Becareful 99 999,9999 - действительное числовое значение в Таиланде.
То же самое в Великобритании @EricF.
Кальмарий: не совсем, см. en.wikipedia.org/wiki/Decimal_mark#Examples_of_use



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Кажется, этот способ работает хорошо:
function IsNumeric(input){
var RE = /^-{0,1}\d*\.{0,1}\d+$/;
return (RE.test(input));
}
В одной строке:
const IsNumeric = (num) => /^-{0,1}\d*\.{0,1}\d+$/.test(num);
И чтобы проверить это:
const IsNumeric = (num) => /^-{0,1}\d*\.{0,1}\d+$/.test(num);
function TestIsNumeric(){
var results = ''
results += (IsNumeric('-1')?"Pass":"Fail") + ": IsNumeric('-1') => true\n";
results += (IsNumeric('-1.5')?"Pass":"Fail") + ": IsNumeric('-1.5') => true\n";
results += (IsNumeric('0')?"Pass":"Fail") + ": IsNumeric('0') => true\n";
results += (IsNumeric('0.42')?"Pass":"Fail") + ": IsNumeric('0.42') => true\n";
results += (IsNumeric('.42')?"Pass":"Fail") + ": IsNumeric('.42') => true\n";
results += (!IsNumeric('99,999')?"Pass":"Fail") + ": IsNumeric('99,999') => false\n";
results += (!IsNumeric('0x89f')?"Pass":"Fail") + ": IsNumeric('0x89f') => false\n";
results += (!IsNumeric('#abcdef')?"Pass":"Fail") + ": IsNumeric('#abcdef') => false\n";
results += (!IsNumeric('1.2.3')?"Pass":"Fail") + ": IsNumeric('1.2.3') => false\n";
results += (!IsNumeric('')?"Pass":"Fail") + ": IsNumeric('') => false\n";
results += (!IsNumeric('blah')?"Pass":"Fail") + ": IsNumeric('blah') => false\n";
return results;
}
console.info(TestIsNumeric());.as-console-wrapper { max-height: 100% !important; top: 0; }Я позаимствовал это регулярное выражение из http://www.codetoad.com/javascript/isnumeric.asp. Объяснение:
/^ match beginning of string
-{0,1} optional negative sign
\d* optional digits
\.{0,1} optional decimal point
\d+ at least one digit
$/ match end of string
// ТАКЖЕ ДОБАВЛЯЕТСЯ К результатам ТЕСТА + = (! IsNumeric ('-')? "Pass": "Fail") + ": IsNumeric ('-') => false \ n"; results + = (! IsNumeric ('01 ')? «Пройдено»: «Неудачно») + «: IsNumeric ('01') => false \ n»; results + = (! IsNumeric ('- 01')? «Пройдено»: «Неудачно») + «: IsNumeric ('- 01') => false \ n»; results + = (! IsNumeric ('000')? «Пройдено»: «Не удалось») + «: IsNumeric ('000') => false \ n»;
Пара тестов, которые нужно добавить:
IsNumeric('01.05') => false
IsNumeric('1.') => false
IsNumeric('.') => false
Я придумал это:
function IsNumeric(input) {
return /^-?(0|[1-9]\d*|(?=\.))(\.\d+)?$/.test(input);
}
Решение охватывает:
Хочу добавить следующее:
1. IsNumeric('0x89f') => true
2. IsNumeric('075') => trueПоложительные шестнадцатеричные числа начинаются с 0x, а отрицательные шестнадцатеричные числа начинаются с -0x.
Положительные числа oct начинаются с 0, а отрицательные числа oct начинаются с -0.
Это учитывает большую часть того, что уже было упомянуто, но включает шестнадцатеричные и восьмеричные числа, отрицательные научные числа, бесконечность и удалило десятичные научные числа (4e3.2 недействителен).
function IsNumeric(input){
var RE = /^-?(0|INF|(0[1-7][0-7]*)|(0x[0-9a-fA-F]+)|((0|[1-9][0-9]*|(?=[\.,]))([\.,][0-9]+)?([eE]-?\d+)?))$/;
return (RE.test(input));
}
Используйте функцию isNaN. Я считаю, что если вы протестируете !isNaN(yourstringhere), он отлично подойдет для любой из этих ситуаций.
Примечание:! IsNaN (null) == true, поскольку Number (null) == 0
если (! (x == null || isNaN (x))) alert ("isNumeric"); // Но это решение принимает 0x40, так что это все еще не то, что нужно оператору.
Обратите внимание, что isNaN ("Infinity") === false, что, вероятно, также не то, что вы хотите (но также не произойдет в реальной жизни).
Да, встроенный isNaN(object) будет намного быстрее, чем любой анализ регулярных выражений, потому что он встроен и скомпилирован, а не интерпретируется на лету.
Хотя результаты несколько отличаются от того, что вы ищете (попытайся):
// IS NUMERIC
document.write(!isNaN('-1') + "<br />"); // true
document.write(!isNaN('-1.5') + "<br />"); // true
document.write(!isNaN('0') + "<br />"); // true
document.write(!isNaN('0.42') + "<br />"); // true
document.write(!isNaN('.42') + "<br />"); // true
document.write(!isNaN('99,999') + "<br />"); // false
document.write(!isNaN('0x89f') + "<br />"); // true
document.write(!isNaN('#abcdef') + "<br />"); // false
document.write(!isNaN('1.2.3') + "<br />"); // false
document.write(!isNaN('') + "<br />"); // true
document.write(!isNaN('blah') + "<br />"); // false
Это можно сделать без RegExp как
function IsNumeric(data){
return parseFloat(data)==data;
}
Если мы используем ==, он вернет истину даже для чисел, представленных в виде строк. Таким образом, «42» будет считаться действительным числом в случае «==» и будет считаться недействительным в случае ===
это возвращает истину для «-0.», «-.0», «.0» и «0».
А-а-а! Не слушайте ответы на регулярные выражения. RegEx неприятен для этого, и я говорю не только о производительности. С регулярным выражением так легко сделать незаметные ошибки, невозможно обнаружить ошибки.
Если вы не можете использовать isNaN(), это должно работать намного лучше:
function IsNumeric(input)
{
return (input - 0) == input && (''+input).trim().length > 0;
}
Вот как это работает:
Выражение (input - 0) заставляет JavaScript выполнять приведение типов к вашему входному значению; сначала его нужно интерпретировать как число для операции вычитания. Если это преобразование в число не удается, выражение приведет к NaN. Этот результат числовой затем сравнивается с исходным значением, которое вы передали. Поскольку левая часть теперь числовая, снова используется приведение типа. Теперь, когда ввод с обеих сторон был приведен к одному и тому же типу из одного и того же исходного значения, можно подумать, что они всегда должны быть одинаковыми (всегда истинными). Однако есть специальное правило, согласно которому NaN никогда не равен NaN, поэтому значение, которое нельзя преобразовать в число (и только значения, которые нельзя преобразовать в числа), приведет к ложному результату.
Проверка длины предназначена для особого случая, связанного с пустыми строками. Также обратите внимание, что он падает на ваш тест 0x89f, но это потому, что во многих средах это нормальный способ определить числовой литерал. Если вы хотите поймать этот конкретный сценарий, вы можете добавить дополнительную проверку. Еще лучше, если это ваша причина не использовать isNaN(), тогда просто оберните свою собственную функцию вокруг isNaN(), которая также может выполнить дополнительную проверку.
Таким образом, если вы хотите узнать, можно ли преобразовать значение в число, попробуйте преобразовать его в число.
Я вернулся и провел некоторое исследование для Почему, пустая строка не дала ожидаемого результата, и я думаю, что теперь понял: пустая строка приводится к 0, а не к NaN. В этом случае достаточно просто обрезать строку перед проверкой длины.
Выполнение модульных тестов для нового кода дает сбой только для бесконечных и логических литералов, и проблема может возникнуть только в том случае, если вы генерируете код (на самом деле, кто будет вводить литерал и проверять, является ли он числовым? Вы должны знать), и это было бы странным кодом для генерации.
Но, опять же, единственная причина использовать это, если по какой-то причине вам нужно избегать isNaN ().
даже лучше, если вам просто нужно учитывать особый случай 0x89f - это обернуть функцию IsNumeric () вокруг isNaN (), которая затем сделает вашу специальную проверку только в том случае, если isNaN () возвращает false.
Это не работает в строках с пробелами, например IsNumeric(' '), IsNumeric('\n\t') и т. д., Все возвращают true
Он также не будет работать с литералами Number. IsNumeric(5) == false; проверит набор модульных тестов, которые я опубликовал, эта функция имеет номер 16 в наборе тестов. stackoverflow.com/questions/18082/…
Мне пришлось изменить этот сценарий и добавить "input.length> = 0;" потому что без знака равенства это не удалось, если поле было полностью пустым.
в jslint: Ошибка: Проблема в строке 3, символ 12: Неожиданный «ввод». return (input - 0) == input && input.length> 0; Проблема в строке 3, символ 23: ожидалось '===', а вместо этого было '=='. return (input - 0) == input && input.length> 0;
Я не могу поверить, что никто не указал на использование регулярного выражения (replace) после предупреждения о неиспользовании регулярных выражений ... Конечно, замена пробелов проще, чем анализ числа, но все же определенно "неприглядно".
@PatrickM Регулярное выражение было добавлено позже, и оно неприятное. Это потому, что IE8 не поддерживает .trim(). Я сниму его после 14 апреля следующего года, когда Windows XP больше не поддерживается MS (XP не может получить IE9). Это должен быть последний гвоздь в гроб IE8.
@JoelCoehoorn I (и многие другие) по-прежнему будут использовать XP после 14 апреля следующего года. И некоторые из них (не я) по-прежнему будут использовать IE8 (или ниже).
@Oriol Это большая проблема ... поскольку после этой даты не было выпущено никаких исправлений безопасности, уход от XP должен быть приоритетом.
@Oriol XP или нет, но если вы используете IE8 или ниже, вы используете ужасно устаревшее программное обеспечение. Конечно, XP не может запускать IE9 +, поэтому используйте Chrome или FF. Люди, жившие в прошлом, использующие IE8, являются отравой для многих веб-разработчиков. Если бы я мог вернуть время, которое я потратил на то, чтобы убедиться, что совершенно хороший код также работает в IE8 ... Для меня взять код, который работает в FF и Chrome, и исправить его для запуска в IE8 примерно так же практично, как взять исполняемый файл Windows 8 и убедившись, что он работает так же в Windows 3.1.
@chiliNUT Нет, я использую Firefox. IE - это кошмар!
@cfqueryparam В мою защиту регулярное выражение - это лишь очень небольшая часть ответа. Он не делает ничего похожего на поиск цифр / десятичных знаков. Теперь, когда IE8 официально мертв (Windows позволяет IE9 или лучше на каждой поддерживаемой платформе), я могу обновить его, чтобы просто использовать .trim () ... и я уже говорил об этом раньше в комментариях
также не удастся начать и завершить 0 (например, '0015' или '1.250')
Yahoo! UI использует это:
isNumber: function(o) {
return typeof o === 'number' && isFinite(o);
}
Это больше проверка типа переменной, а не содержимого числа. Он также не будет работать с числами, созданными с помощью new Number(1).
Как говорит Алекс, это на самом деле не отвечает на поставленный вопрос, так как это не сработает, если o = "1001".
function IsNumeric(num) {
return (num >=0 || num < 0);
}
Это также работает для чисел типа 0x23.
IsNumeric(''), IsNumeric(' '), IsNumeric(true), IsNumeric(false), IsNumeric(null) возвращают true вместо false.
@ Ответ Джоэла довольно близок, но он не сработает в следующих случаях:
// Whitespace strings:
IsNumeric(' ') == true;
IsNumeric('\t\t') == true;
IsNumeric('\n\r') == true;
// Number literals:
IsNumeric(-1) == false;
IsNumeric(0) == false;
IsNumeric(1.1) == false;
IsNumeric(8e5) == false;
Некоторое время назад мне пришлось реализовать функцию IsNumeric, чтобы узнать, содержит ли переменная числовое значение, независимо от его типа, это может быть String, содержащий числовое значение (мне пришлось учитывать также экспоненциальную нотацию и т. д.), Объект Number, практически все, что можно было передать этой функции, я не мог делать никаких предположений о типах, заботясь о приведении типов (например, +true == 1;, но true не следует рассматривать как "numeric").
Я думаю, что стоит поделиться этим набором +30 юнит-тестов, сделанным для многочисленных реализаций функций, а также поделиться тем, который проходит все мои тесты:
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
P.S.isNaN и isFinite имеют сбивающее с толку поведение из-за принудительного преобразования в число. В ES6 Number.isNaN & Number.isFinite исправит эти проблемы. Имейте это в виду при их использовании.
Обновлять: Вот как это делает сейчас jQuery (стабильная версия 2.2):
isNumeric: function(obj) {
var realStringObj = obj && obj.toString();
return !jQuery.isArray(obj) && (realStringObj - parseFloat(realStringObj) + 1) >= 0;
}
Обновлять: Угловой 4.3:
export function isNumeric(value: any): boolean {
return !isNaN(value - parseFloat(value));
}
это не работает с другими языковыми стандартами, где мы используем десятичные запятые, но добавляем `n = n.replace (/, /,". "); ' перед возвращением исправить.
Однако не работает с действительно большими числами, например 2e308.
@RobG, такое поведение является преднамеренным, 2e308 > Number.MAX_VALUE начиная с 2e308 == Infinity. Если вам нужна функция, которая возвращает true также для значений положительной и отрицательной бесконечности, проверьте функцию № 2 в тестирование. Ваше здоровье.
Действительно ли isFinite нужен? isNaN (1/0) должен возвращать false, верно?
isNaN (1/0) возвращает false ... тогда да, нам нужен isFinite, чтобы держать его под контролем, понятно. Круто!
@slf: isNaN(1/0) возвращает false, но я возвращаю его отрицательный результат. Если мы удалим вызов isFinite, как вы предлагаете, положительная и отрицательная бесконечность будут «допустимыми значениями» (вы можете захотеть или не захотеть этого поведения), но также и числовые строки с завершающими символами будут ошибочно проходить, например, "7.2acdgs" ... Проверьте функцию № 4 в тестирование ...
Кстати, юнит-тесты сейчас используются проект jQuery
jQuery теперь также является с помощью этой реализацией.
isNumber (3.,. 4) ==> правда, но не должно?
@Orhun Alp Oral: Я считаю, что число перед запятой передается как параметр n. Другими словами, он проверяет, является ли 3. числом: что это такое.
Отрицательные шестнадцатеричные строковые литералы не работают.
@Wk_of_Angmar вы считаете шестнадцатеричные числа числовыми?
@ vol7ron: То, что я думаю, на самом деле не имеет значения. Я просто информирую других людей об этом факте, поскольку тесты требуют, чтобы положительные шестнадцатеричные строковые литералы проверялись как число (и, в стороне, мне нужна была функция для проверки отрицательных шестнадцатеричных строковых литералов как числа). (И да, я понимаю, что отрицательные шестнадцатеричные строковые литералы также не преобразуются в числа с помощью vanilla JS.) "0x44"*1 -> 68, "-0x44"*1 -> NaN в обычном JS.
Блестяще! Иногда, когда функция такая короткая, она становится нечитаемой, но при этом сохраняется ее удобочитаемость, но при этом она элегантно краткая. Спасибо.
Это просто оболочка для parseFloat, которая выполняет фактическую работу и с тех пор является правильным способом преобразования в числа. Я не понимаю, в чем дело.
Если вы проверяете, является ли вся строка допустимым числом, будьте осторожны. Строки, содержащие лишние пробелы, вернут истину: «1234» (пробел в качестве последнего символа) ==> истина.
Это даже лучше !isNaN(+val) && isFinite(val). Подробности вы можете прочитать в моем ответе ниже.
@Wk_of_Angmar Я считаю, что он проверяет 0.4, когда вы передаете 3.,.4 в.
@navie: Нет, я так не думаю. Функции JavaScript могут быть переменными, а аргументы разделяются запятыми. Первый аргумент отображается на переменную n. Попробуйте сами: function tellMe (n) {alert (n); } tellMe (3.,. 4);
Решение здесь - просто использовать JQuery. Теперь у них есть еще лучшая реализация этого: github.com/jquery/jquery/blob/master/src/core.js#L230
Не работает для таких значений, как 5-, 5-, 5 ++.
А что насчет таких вещей, как [0]?
isNumber завершается ошибкой, если это строка, которая выглядит так: "20,1".
Обратите внимание, что isNumber([-1]) вернет true. Вероятно, поэтому jQuery сначала проверяет массивы.
Это работает с «-50», но не работает с «(50)». Я использую его для обозначения валют, и иногда скобки используются для обозначения отрицательных значений.
Использование Number.isNaN и Number.isFinite приведет к ложному значению для всех строк, но будет работать для фактических значений Number. Это именно то, чего хочет я, но это не ответ на этот вопрос.
отличный ответ и комментарии, NaN также должен быть тестовым примером.
как насчет "078332e437"
Мне нужна была реализация, которая рассматривает бесконечность как число, поэтому я использовал еще одну из реализаций на странице:! IsNaN (строка) &&! IsNaN (parseFloat (строка))
Это не для "12345"
как насчет null?
насчет ['4'] и new Number(), я исправил, !(n instanceof Array) && !isNaN(parseFloat(n)) && isFinite(n) прошел все тесты
Для меня это лучший способ:
isNumber : function(v){
return typeof v === 'number' && isFinite(v);
}
К сожалению, это своего рода СТРОГАЯ программа проверки чисел, которая не сработает для любой строки, содержащей только числовые буквы, например "0" и т. д.
Это должно сработать. Некоторые из представленных здесь функций ошибочны и также должны быть быстрее, чем любые другие функции здесь.
function isNumeric(n)
{
var n2 = n;
n = parseFloat(n);
return (n!='NaN' && n2==n);
}
Объяснил:
Создайте свою копию, затем преобразует число в число с плавающей запятой, затем сравнивает себя с исходным числом, если это все еще число (целое или плавающее), и совпадает с исходным числом, что означает, что это действительно число.
Он работает как с числовыми строками, так и с простыми числами. Не работает с шестнадцатеричными числами.
Предупреждение: используйте на свой страх и риск, никаких гарантий.
@Alex, по крайней мере, имейте собственное мнение о вещах. Не просто все время критикуйте.
Следующее также может сработать.
function isNumeric(v) {
return v.length > 0 && !isNaN(v) && v.search(/[A-Z]|[#]/ig) == -1;
};
return (input - 0) == input && input.length > 0;
у меня не сработало. Когда я поставил предупреждение и проверил, input.length был undefined. Я думаю, что нет свойства проверять целочисленную длину. Так что я сделал
var temp = '' + input;
return (input - 0) == input && temp.length > 0;
Работало нормально.
Мое решение,
function isNumeric(input) {
var number = /^\-{0,1}(?:[0-9]+){0,1}(?:\.[0-9]+){0,1}$/i;
var regex = RegExp(number);
return regex.test(input) && input.length>0;
}
Кажется, это работает в любой ситуации, но я могу ошибаться.
Это регулярное выражение было бы менее запутанным, если бы вы не использовали ненужные escape-символы, используйте ? для {0,1} и \d для [0-9]. Также + и затем обернув его (?:){0,1}, вы также можете использовать * и забыть о (не) захватывающих группах.
Целочисленное значение можно проверить с помощью:
function isNumeric(value) {
var bool = isNaN(+value));
bool = bool || (value.indexOf('.') != -1);
bool = bool || (value.indexOf(",") != -1);
return !bool;
};
Так проще и быстрее! Все тесты проверены!
@Zoltan Lengyel Комментарий "другие регионы" (26 апр в 2:14) в ответе @CMS в декабре (02 '09, в 5:36):
Я бы порекомендовал протестировать typeof (n) === 'string':
function isNumber(n) {
if (typeof (n) === 'string') {
n = n.replace(/,/, ".");
}
return !isNaN(parseFloat(n)) && isFinite(n);
}
Это расширяет рекомендацию Zoltans, чтобы иметь возможность тестировать не только «локализованные числа», такие как isNumber('12,50'), но и «чистые» числа, такие как isNumber(2011).
Ну, я использую тот, который сделал ...
Пока работает:
function checkNumber(value) {
if ( value % 1 == 0 )
return true;
else
return false;
}
Если вы заметили какие-то проблемы, скажите, пожалуйста.
Подобно тому, как любые числа должны делиться на единицу без остатка, я решил, что могу просто использовать модуль, и если вы попытаетесь разделить строку на число, результат будет не таким. Так.
Что насчет 1.5? Кроме того, в теле функции много избыточного кода. Вы должны напрямую вернуть результат выражения, который будет логическим.
Если я не ошибаюсь, это должно соответствовать любому допустимому числовому значению JavaScript, за исключением констант (Infinity, NaN) и знаковых операторов + / - (поскольку на самом деле они не являются частью числа, насколько я понимаю, это отдельные операторы. ):
Мне это было нужно для токенизатора, где отправка числа в JavaScript для оценки не была вариантом ... Это определенно не самое короткое из возможных регулярных выражений, но я считаю, что оно улавливает все тонкости синтаксиса чисел JavaScript.
/^(?:(?:(?:[1-9]\d*|\d)\.\d*|(?:[1-9]\d*|\d)?\.\d+|(?:[1-9]\d*|\d))
(?:[e]\d+)?|0[0-7]+|0x[0-9a-f]+)$/i
Допустимые числа будут включать:
- 0
- 00
- 01
- 10
- 0e1
- 0e01
- .0
- 0.
- .0e1
- 0.e1
- 0.e00
- 0xf
- 0Xf
Недействительные числа будут
- 00e1
- 01e1
- 00.0
- 00x0
- .
- .e0
Я использую более простое решение:
function isNumber(num) {
return parseFloat(num).toString() == num
}
это не сработает ни на чем с лишними 0 в конце. пример: «10.0»
Здесь я собрал «хорошие» с этой страницы и поместил их в простой тестовый шаблон, чтобы вы могли оценить его самостоятельно.
Для новичков console.info - это встроенная функция (доступная во всех современных браузерах), которая позволяет выводить результаты в консоль JavaScript (покопайтесь, вы найдете это) вместо вывода на вашу HTML-страницу.
var isNumeric = function(val){
// --------------------------
// Recommended
// --------------------------
// jQuery - works rather well
// See CMS's unit test also: http://dl.getdropbox.com/u/35146/js/tests/isNumber.html
return !isNaN(parseFloat(val)) && isFinite(val);
// Aquatic - good and fast, fails the "0x89f" test, but that test is questionable.
//return parseFloat(val)==val;
// --------------------------
// Other quirky options
// --------------------------
// Fails on "", null, newline, tab negative.
//return !isNaN(val);
// user532188 - fails on "0x89f"
//var n2 = val;
//val = parseFloat(val);
//return (val!='NaN' && n2==val);
// Rafael - fails on negative + decimal numbers, may be good for isInt()?
// return ( val % 1 == 0 ) ? true : false;
// pottedmeat - good, but fails on stringy numbers, which may be a good thing for some folks?
//return /^-?(0|[1-9]\d*|(?=\.))(\.\d+)?$/.test(val);
// Haren - passes all
// borrowed from http://www.codetoad.com/javascript/isnumeric.asp
//var RE = /^-{0,1}\d*\.{0,1}\d+$/;
//return RE.test(val);
// YUI - good for strict adherance to number type. Doesn't let stringy numbers through.
//return typeof val === 'number' && isFinite(val);
// user189277 - fails on "" and "\n"
//return ( val >=0 || val < 0);
}
var tests = [0, 1, "0", 0x0, 0x000, "0000", "0x89f", 8e5, 0x23, -0, 0.0, "1.0", 1.0, -1.5, 0.42, '075', "01", '-01', "0.", ".0", "a", "a2", true, false, "#000", '1.2.3', '#abcdef', '', "", "\n", "\t", '-', null, undefined];
for (var i=0; i<tests.length; i++){
console.info( "test " + i + ": " + tests[i] + " \t " + isNumeric(tests[i]) );
}
Начиная с jQuery 1.7 вы можете использовать jQuery.isNumeric():
$.isNumeric('-1'); // true
$.isNumeric('-1.5'); // true
$.isNumeric('0'); // true
$.isNumeric('0.42'); // true
$.isNumeric('.42'); // true
$.isNumeric('0x89f'); // true (valid hexa number)
$.isNumeric('99,999'); // false
$.isNumeric('#abcdef'); // false
$.isNumeric('1.2.3'); // false
$.isNumeric(''); // false
$.isNumeric('blah'); // false
Просто обратите внимание, что в отличие от того, что вы сказали, 0x89f - действительное число (шестнадцатеричное).
OP хочет действительный номер десятичный, поэтому jQuery isNumeric не подходит. Это также не работает для очень больших чисел.
Принятый ответ не прошел ваш тест №7, и я думаю, это потому, что вы передумали. Итак, это ответ на принятый ответ, с которым у меня возникли проблемы.
Во время некоторых проектов мне нужно было проверить некоторые данные и быть как можно более уверенным в том, что это числовое значение javascript, которое можно использовать в математических операциях.
jQuery и некоторые другие библиотеки javascript уже включают такую функцию, обычно называемую isNumeric. Существует также опубликовать в stackoverflow, который широко используется в качестве ответа, та же самая общая процедура, которую используют вышеупомянутые библиотеки.
function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
Во-первых, приведенный выше код вернет истину, если аргумент был массивом длины 1, и этот единственный элемент имел тип, который вышеупомянутой логикой считался числовым. На мой взгляд, если это массив, то он не числовой.
Чтобы решить эту проблему, я добавил проверку на массивы скидок из логики
function isNumber(n) {
return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n);
}
Конечно, вы также можете использовать Array.isArray, jquery $.isArray или прототип Object.isArray вместо Object.prototype.toString.call(n) !== '[object Array]'.
Моя вторая проблема заключалась в том, что строки отрицательных шестнадцатеричных целочисленных литералов («-0xA» -> -10) не считались числовыми. Однако строки положительных шестнадцатеричных целочисленных литералов («0xA» -> 10) обрабатывались как числовые. Мне нужно, чтобы оба были действительными числовыми.
Затем я изменил логику, чтобы учесть это.
function isNumber(n) {
return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
}
Если вы беспокоитесь о создании регулярного выражения каждый раз, когда вызывается функция, вы можете переписать его в закрытии, что-то вроде этого
var isNumber = (function () {
var rx = /^-/;
return function (n) {
return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(rx, ''));
};
}());
Затем я взял CMS +30 тестовых случаев и клонировал тестирование на jsfiddle, добавил мои дополнительные тестовые примеры и описанное выше решение.
Он может не заменить широко распространенный / используемый ответ, но если это больше того, чего вы ожидаете в результате вашей функции isNumeric, то, надеюсь, это будет некоторая помощь.
Обновлено: Как указано в Берги, существуют другие возможные объекты, которые можно рассматривать как числовые, и было бы лучше занести в белый список, чем в черный. Имея это в виду, я бы добавил критерии.
Я хочу, чтобы моя функция isNumeric учитывала только числа или строки
Имея это в виду, было бы лучше использовать
function isNumber(n) {
return (Object.prototype.toString.call(n) === '[object Number]' || Object.prototype.toString.call(n) === '[object String]') &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
}
Протестируйте решения
var testHelper = function() {
var testSuite = function() {
test("Integer Literals", function() {
ok(isNumber("-10"), "Negative integer string");
ok(isNumber("0"), "Zero string");
ok(isNumber("5"), "Positive integer string");
ok(isNumber(-16), "Negative integer number");
ok(isNumber(0), "Zero integer number");
ok(isNumber(32), "Positive integer number");
ok(isNumber("040"), "Octal integer literal string");
ok(isNumber(0144), "Octal integer literal");
ok(isNumber("-040"), "Negative Octal integer literal string");
ok(isNumber(-0144), "Negative Octal integer literal");
ok(isNumber("0xFF"), "Hexadecimal integer literal string");
ok(isNumber(0xFFF), "Hexadecimal integer literal");
ok(isNumber("-0xFF"), "Negative Hexadecimal integer literal string");
ok(isNumber(-0xFFF), "Negative Hexadecimal integer literal");
});
test("Foating-Point Literals", function() {
ok(isNumber("-1.6"), "Negative floating point string");
ok(isNumber("4.536"), "Positive floating point string");
ok(isNumber(-2.6), "Negative floating point number");
ok(isNumber(3.1415), "Positive floating point number");
ok(isNumber(8e5), "Exponential notation");
ok(isNumber("123e-2"), "Exponential notation string");
});
test("Non-Numeric values", function() {
equals(isNumber(""), false, "Empty string");
equals(isNumber(" "), false, "Whitespace characters string");
equals(isNumber("\t\t"), false, "Tab characters string");
equals(isNumber("abcdefghijklm1234567890"), false, "Alphanumeric character string");
equals(isNumber("xabcdefx"), false, "Non-numeric character string");
equals(isNumber(true), false, "Boolean true literal");
equals(isNumber(false), false, "Boolean false literal");
equals(isNumber("bcfed5.2"), false, "Number with preceding non-numeric characters");
equals(isNumber("7.2acdgs"), false, "Number with trailling non-numeric characters");
equals(isNumber(undefined), false, "Undefined value");
equals(isNumber(null), false, "Null value");
equals(isNumber(NaN), false, "NaN value");
equals(isNumber(Infinity), false, "Infinity primitive");
equals(isNumber(Number.POSITIVE_INFINITY), false, "Positive Infinity");
equals(isNumber(Number.NEGATIVE_INFINITY), false, "Negative Infinity");
equals(isNumber(new Date(2009, 1, 1)), false, "Date object");
equals(isNumber(new Object()), false, "Empty object");
equals(isNumber(function() {}), false, "Instance of a function");
equals(isNumber([]), false, "Empty Array");
equals(isNumber(["-10"]), false, "Array Negative integer string");
equals(isNumber(["0"]), false, "Array Zero string");
equals(isNumber(["5"]), false, "Array Positive integer string");
equals(isNumber([-16]), false, "Array Negative integer number");
equals(isNumber([0]), false, "Array Zero integer number");
equals(isNumber([32]), false, "Array Positive integer number");
equals(isNumber(["040"]), false, "Array Octal integer literal string");
equals(isNumber([0144]), false, "Array Octal integer literal");
equals(isNumber(["-040"]), false, "Array Negative Octal integer literal string");
equals(isNumber([-0144]), false, "Array Negative Octal integer literal");
equals(isNumber(["0xFF"]), false, "Array Hexadecimal integer literal string");
equals(isNumber([0xFFF]), false, "Array Hexadecimal integer literal");
equals(isNumber(["-0xFF"]), false, "Array Negative Hexadecimal integer literal string");
equals(isNumber([-0xFFF]), false, "Array Negative Hexadecimal integer literal");
equals(isNumber([1, 2]), false, "Array with more than 1 Positive interger number");
equals(isNumber([-1, -2]), false, "Array with more than 1 Negative interger number");
});
}
var functionsToTest = [
function(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
},
function(n) {
return !isNaN(n) && !isNaN(parseFloat(n));
},
function(n) {
return !isNaN((n));
},
function(n) {
return !isNaN(parseFloat(n));
},
function(n) {
return typeof(n) != "boolean" && !isNaN(n);
},
function(n) {
return parseFloat(n) === Number(n);
},
function(n) {
return parseInt(n) === Number(n);
},
function(n) {
return !isNaN(Number(String(n)));
},
function(n) {
return !isNaN(+('' + n));
},
function(n) {
return (+n) == n;
},
function(n) {
return n && /^-?\d+(\.\d+)?$/.test(n + '');
},
function(n) {
return isFinite(Number(String(n)));
},
function(n) {
return isFinite(String(n));
},
function(n) {
return !isNaN(n) && !isNaN(parseFloat(n)) && isFinite(n);
},
function(n) {
return parseFloat(n) == n;
},
function(n) {
return (n - 0) == n && n.length > 0;
},
function(n) {
return typeof n === 'number' && isFinite(n);
},
function(n) {
return !Array.isArray(n) && !isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
}
];
// Examines the functionsToTest array, extracts the return statement of each function
// and fills the toTest select element.
var fillToTestSelect = function() {
for (var i = 0; i < functionsToTest.length; i++) {
var f = functionsToTest[i].toString();
var option = /[\s\S]*return ([\s\S]*);/.exec(f)[1];
$("#toTest").append('<option value = "' + i + '">' + (i + 1) + '. ' + option + '</option>');
}
}
var performTest = function(functionNumber) {
reset(); // Reset previous test
$("#tests").html(""); //Clean test results
isNumber = functionsToTest[functionNumber]; // Override the isNumber global function with the one to test
testSuite(); // Run the test
// Get test results
var totalFail = 0;
var totalPass = 0;
$("b.fail").each(function() {
totalFail += Number($(this).html());
});
$("b.pass").each(function() {
totalPass += Number($(this).html());
});
$("#testresult").html(totalFail + " of " + (totalFail + totalPass) + " test failed.");
$("#banner").attr("class", "").addClass(totalFail > 0 ? "fail" : "pass");
}
return {
performTest: performTest,
fillToTestSelect: fillToTestSelect,
testSuite: testSuite
};
}();
$(document).ready(function() {
testHelper.fillToTestSelect();
testHelper.performTest(0);
$("#toTest").change(function() {
testHelper.performTest($(this).children(":selected").val());
});
});<script src = "https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" type = "text/javascript"></script>
<script src = "https://rawgit.com/Xotic750/testrunner-old/master/testrunner.js" type = "text/javascript"></script>
<link href = "https://rawgit.com/Xotic750/testrunner-old/master/testrunner.css" rel = "stylesheet" type = "text/css">
<h1>isNumber Test Cases</h1>
<h2 id = "banner" class = "pass"></h2>
<h2 id = "userAgent">Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11</h2>
<div id = "currentFunction"></div>
<div id = "selectFunction">
<label for = "toTest" style = "font-weight:bold; font-size:Large;">Select function to test:</label>
<select id = "toTest" name = "toTest">
</select>
</div>
<div id = "testCode"></div>
<ol id = "tests">
<li class = "pass">
<strong>Integer Literals <b style = "color:black;">(0, 10, 10)</b></strong>
<ol style = "display: none;">
<li class = "pass">Negative integer string</li>
<li class = "pass">Zero string</li>
<li class = "pass">Positive integer string</li>
<li class = "pass">Negative integer number</li>
<li class = "pass">Zero integer number</li>
<li class = "pass">Positive integer number</li>
<li class = "pass">Octal integer literal string</li>
<li class = "pass">Octal integer literal</li>
<li class = "pass">Hexadecimal integer literal string</li>
<li class = "pass">Hexadecimal integer literal</li>
</ol>
</li>
<li class = "pass">
<strong>Foating-Point Literals <b style = "color:black;">(0, 6, 6)</b></strong>
<ol style = "display: none;">
<li class = "pass">Negative floating point string</li>
<li class = "pass">Positive floating point string</li>
<li class = "pass">Negative floating point number</li>
<li class = "pass">Positive floating point number</li>
<li class = "pass">Exponential notation</li>
<li class = "pass">Exponential notation string</li>
</ol>
</li>
<li class = "pass">
<strong>Non-Numeric values <b style = "color:black;">(0, 18, 18)</b></strong>
<ol style = "display: none;">
<li class = "pass">Empty string: false</li>
<li class = "pass">Whitespace characters string: false</li>
<li class = "pass">Tab characters string: false</li>
<li class = "pass">Alphanumeric character string: false</li>
<li class = "pass">Non-numeric character string: false</li>
<li class = "pass">Boolean true literal: false</li>
<li class = "pass">Boolean false literal: false</li>
<li class = "pass">Number with preceding non-numeric characters: false</li>
<li class = "pass">Number with trailling non-numeric characters: false</li>
<li class = "pass">Undefined value: false</li>
<li class = "pass">Null value: false</li>
<li class = "pass">NaN value: false</li>
<li class = "pass">Infinity primitive: false</li>
<li class = "pass">Positive Infinity: false</li>
<li class = "pass">Negative Infinity: false</li>
<li class = "pass">Date object: false</li>
<li class = "pass">Empty object: false</li>
<li class = "pass">Instance of a function: false</li>
</ol>
</li>
</ol>
<div id = "main">
This page contains tests for a set of isNumber functions. To see them, take a look at the source.
</div>
<div>
<p class = "result">Tests completed in 0 milliseconds.
<br>0 tests of 0 failed.</p>
</div>На мой взгляд, это наиболее защищенная функция; последний. Принятый ответ охватывает, вероятно, 99,99% всех случаев, но в этом случае, вероятно, 100% а) случаев с небольшими накладными расходами.
Вы забыли о литерале с плавающей запятой "99,999". Это действительный номер во всей Европе, кроме Великобритании.
Это не было забыто, это не было чем-то, что я считал числовым в смысле чисел Javascript, OP также заявил, что IsNumeric('99,999') => false
knockoutJs Функции проверки встроенной библиотеки
Расширяя его, поле проверяется
1) номер
self.number = ko.observable(numberValue).extend ({число: истина});
Прецедент
numberValue = '0.0' --> true
numberValue = '0' --> true
numberValue = '25' --> true
numberValue = '-1' --> true
numberValue = '-3.5' --> true
numberValue = '11.112' --> true
numberValue = '0x89f' --> false
numberValue = '' --> false
numberValue = 'sfsd' --> false
numberValue = 'dg##$' --> false
2) цифра
self.number = ko.observable(numberValue).extend ({digit: true});
Прецедент
numberValue = '0' --> true
numberValue = '25' --> true
numberValue = '0.0' --> false
numberValue = '-1' --> false
numberValue = '-3.5' --> false
numberValue = '11.112' --> false
numberValue = '0x89f' --> false
numberValue = '' --> false
numberValue = 'sfsd' --> false
numberValue = 'dg##$' --> false
3) мин. И макс.
self.number = ko.observable(numberValue).extend ({min: 5}). extend ({max: 10});
Это поле принимает только значения от 5 до 10.
Прецедент
numberValue = '5' --> true
numberValue = '6' --> true
numberValue = '6.5' --> true
numberValue = '9' --> true
numberValue = '11' --> false
numberValue = '0' --> false
numberValue = '' --> false
@CMS 'ответ: ваш фрагмент не удался в случаях пробелов на моем компьютере с использованием nodejs. Так что я объединил это с @ ответ Джоэла на следующее:
is_float = function(v) {
return !isNaN(v) && isFinite(v) &&
(typeof(v) == 'number' || v.replace(/^\s+|\s+$/g, '').length > 0);
}
Я протестировал это с теми случаями, которые являются плавающими:
var t = [
0,
1.2123,
'0',
'2123.4',
-1,
'-1',
-123.423,
'-123.432',
07,
0xad,
'07',
'0xad'
];
и те случаи, которые не являются плавающими (включая пустые пробелы и объекты / массивы):
var t = [
'hallo',
[],
{},
'jklsd0',
'',
"\t",
"\n",
' '
];
Здесь все работает как положено. Может это поможет.
Полный исходный код для этого можно найти здесь.
Вот немного улучшенная версия (вероятно, самый быстрый способ), которую я использую вместо точного варианта jQuery, я действительно не знаю, почему они не используют этот:
function isNumeric(val) {
return !isNaN(+val) && isFinite(val);
}
Обратной стороной версии jQuery является то, что если вы передадите строку с начальными цифрами и конечными буквами, например "123abc", parseFloat | parseInt извлечет числовую дробь и вернет 123, НО, второй охранник isFinite все равно откажет.
С унарным оператором + он умрет на первом же посту, т.к. + выкидывает NaN для таких гибридов :)
Небольшая производительность, но я считаю солидный семантический выигрыш.
Остерегайтесь унарного '+' вызовет valueOf () для объекта - см. Этот jsfiddle. Также это не работает с ведущими пробелами, как и ведущий ответ.
Единственная проблема, с которой я столкнулся с отвечать @ CMS, - это исключение NaN и Infinity, которые являются полезными числами во многих ситуациях. Один из способов проверить NaN - это проверить числовые значения, которые не равны самим себе, NaN != NaN! Итак, на самом деле есть 3 теста, с которыми вы хотели бы разобраться ...
function isNumber(n) {
n = parseFloat(n);
return !isNaN(n) || n != n;
}
function isFiniteNumber(n) {
n = parseFloat(n);
return !isNaN(n) && isFinite(n);
}
function isComparableNumber(n) {
n = parseFloat(n);
return (n >=0 || n < 0);
}
isFiniteNumber('NaN')
false
isFiniteNumber('OxFF')
true
isNumber('NaN')
true
isNumber(1/0-1/0)
true
isComparableNumber('NaN')
false
isComparableNumber('Infinity')
true
Мой isComparableNumber довольно близок к другому элегантному отвечать, но обрабатывает шестнадцатеричные и другие строковые представления чисел.
Я нашел простое решение, возможно, не лучшее, но оно работает нормально :)
Итак, что я делаю дальше, я анализирую строку до Int и проверяю, совпадает ли размер длины новой переменной, которая теперь имеет тип int, с длиной исходной строковой переменной. Логически, если размер такой же, это означает, что строка полностью анализируется до int, а это возможно только в том случае, если строка "сделана" только из чисел.
var val=1+$(e).val()+'';
var n=parseInt(val)+'';
if (val.length == n.length )alert('Is int');
Вы можете легко поместить этот код в функцию и вместо предупреждения использовать return true, если int. Помните, что если вы используете точку или запятую в строке, вы проверяете, что она все еще ложна, потому что вы анализируете до int.
Примечание: добавление 1+ в e.val, чтобы начальный ноль не удалялся.
Я выполнил следующее ниже, и он проходит все тестовые случаи ...
Он использует другой способ обработки входных данных parseFloat и Number ...
function IsNumeric(_in) {
return (parseFloat(_in) === Number(_in) && Number(_in) !== NaN);
}
Я не пробовал это, но просто совет: вы можете уменьшить это, чтобы просто вернуть выражение if, например return parseFloat...
@Michael Haren, глупый я, я только что видел эту ссылку http://dl.dropboxusercontent.com/u/35146/js/tests/isNumber.html в наивысшем голосовании (около 30+ тестовых случаев), многое объясняет ...
Это неправильно, вы не можете сравнивать NaN с ==, ===, != или !==, он всегда возвращает false.
Сложность NaN заключается в том, что она не равна каждому значению JavaScript, включая его самого. Таким образом, anythingAtAll === NaN неверен, а anythingAtAll !== NaN верен. Вы проверяете NaN, сравнивая значение с самим собой: x !== x истинно, если x равно NaN, и false в противном случае.
@jkdev Вы также можете использовать isNaN(NaN), который вернет true. Это встроенная функция JavaScript. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Следующее, кажется, отлично работает во многих случаях:
function isNumeric(num) {
return (num > 0 || num === 0 || num === '0' || num < 0) && num !== true && isFinite(num);
}
Это построено на основе этого ответа (который также относится к этому ответу): https://stackoverflow.com/a/1561597/1985601
Я понимаю, что в исходном вопросе не упоминается jQuery, но если вы используете jQuery, вы можете:
$.isNumeric(val)
Простой.
https://api.jquery.com/jQuery.isNumeric/ (начиная с jQuery 1.7)
Я понимаю, что на этот вопрос много раз отвечали, но следующий вариант - достойный кандидат, который может быть полезен в некоторых сценариях.
Следует отметить, что предполагается, что «.42» НЕ является числом, а «4». НЕ является числом, поэтому это следует учитывать.
function isDecimal(x) {
return '' + x === '' + +x;
}
function isInteger(x) {
return '' + x === '' + parseInt(x);
}
isDecimal проходит следующий тест:
function testIsNumber(f) {
return f('-1') && f('-1.5') && f('0') && f('0.42')
&& !f('.42') && !f('99,999') && !f('0x89f')
&& !f('#abcdef') && !f('1.2.3') && !f('') && !f('blah');
}
Идея здесь в том, что каждое число или целое число имеет одно «каноническое» строковое представление, и каждое неканоническое представление должно быть отклонено. Итак, мы приводим преобразование к числу и обратно и смотрим, является ли результат исходной строкой.
Полезны ли эти функции для вас, зависит от варианта использования. Одна особенность - это отдельные строки представляют разные числа (если оба проходят тест isNumber()).
Это актуально, например, для чисел в качестве имен свойств объекта.
var obj = {};
obj['4'] = 'canonical 4';
obj['04'] = 'alias of 4';
obj[4]; // prints 'canonical 4' to the console.
Я использую этот способ, чтобы проверить, является ли переменная числовой:
v * 1 == v
Проблема: false * 1 == false соответствует true.
function isNumber(n) {
return (n===n+''||n===n-0) && n*0==0 && /\S/.test(n);
}
Пояснения:
(n===n-0||n===n+'') проверяет, является ли n числом или строкой (отбрасывает массивы, логическое значение, дату, нуль, ...). Вы можете заменить (n===n-0||n===n+'') на n!==undefined && n!==null && (n.constructor===Number||n.constructor===String): значительно быстрее, но менее лаконично.
n*0==0 проверяет, является ли n конечным числом, как это делает isFinite(n). Если вам нужно проверить строки, представляющие отрицательное шестнадцатеричное число, просто замените n*0==0 чем-то вроде n.toString().replace(/^\s*-/,'')*0==0.
.
Стоит, конечно, немного, поэтому, если он вам не нужен, не используйте его.
/\S/.test(n) отбрасывает пустые строки или строки, содержащие только пробелы (необходимо, поскольку в этом случае isFinite(n) or n*0==0 возвращает положительный результат false). Вы можете уменьшить количество вызовов .test(n), используя (n!=0||/0/.test(n)) вместо /\S/.test(n), или вы можете использовать немного более быстрый, но менее сжатый тест, такой как (n!=0||(n+'').indexOf('0')>=0): небольшое улучшение.
Ни один из ответов не возвращает false для пустых строк, исправление для этого ...
function is_numeric(n)
{
return (n != '' && !isNaN(parseFloat(n)) && isFinite(n));
}
Можно использовать библиотеку проверки типов, например https://github.com/arasatasaygin/is.js, или просто извлечь оттуда контрольный фрагмент (https://github.com/arasatasaygin/is.js/blob/master/is.js#L131):
is.nan = function(value) { // NaN is number :)
return value !== value;
};
// is a given value number?
is.number = function(value) {
return !is.nan(value) && Object.prototype.toString.call(value) === '[object Number]';
};
В общем, если вам нужно проверить типы параметров (в точке входа в вызов функции), вы можете использовать JSDOC-совместимые контракты (https://www.npmjs.com/package/bycontract):
/**
* This is JSDOC syntax
* @param {number|string} sum
* @param {Object.<string, string>} payload
* @param {function} cb
*/
function foo( sum, payload, cb ) {
// Test if the contract is respected at entry point
byContract( arguments, [ "number|string", "Object.<string, string>", "function" ] );
}
// Test it
foo( 100, { foo: "foo" }, function(){}); // ok
foo( 100, { foo: 100 }, function(){}); // exception
Если вам нужно проверить специальный набор десятичных знаков y вы можете использовать этот простой javascript:
http://codesheet.org/codesheet/x1kI7hAD
<input type = "text" name = "date" value = "" pattern = "[0-9]){1,2}(\.){1}([0-9]){2}" maxlength = "6" placeholder = "od npr.: 16.06" onchange = "date(this);" />
Javascript:
function date(inputField) {
var isValid = /^([0-9]){1,2}(\.){1}([0-9]){2}$/.test(inputField.value);
if (isValid) {
inputField.style.backgroundColor = '#bfa';
} else {
inputField.style.backgroundColor = '#fba';
}
return isValid;
}
isNumeric=(el)=>{return Boolean(parseFloat(el)) && isFinite(el)}
Ничего особенного, но мы можем использовать логический конструктор
Чтобы проверить, содержит ли переменная действительное число, а не
просто строка, которая выглядит как число,
Number.isFinite(value) можно использовать.
Это часть языка, так как ES2015
Примеры:
Number.isFinite(Infinity) // false
Number.isFinite(NaN) // false
Number.isFinite(-Infinity) // false
Number.isFinite(0) // true
Number.isFinite(2e64) // true
Number.isFinite('0') // false
Number.isFinite(null) // false
Я предполагаю, что многие люди обращаются к этому вопросу для анализа пользовательского ввода, который обычно будет нить. Этот ответ не работает в тех случаях, как вы правильно указываете в примерах, например. Number.isFinite('0') -> false
Вы совершенно правы. Я попытался сделать это ясно спереди.
function isNumeric(n) {
var isNumber = true;
$.each(n.replace(/ /g,'').toString(), function(i, v){
if (v!=',' && v!='.' && v!='-'){
if (isNaN(v)){
isNumber = false;
return false;
}
}
});
return isNumber;
}
isNumeric(-3,4567.89); // true <br>
isNumeric(3,4567.89); // true <br>
isNumeric("-3,4567.89"); // true <br>
isNumeric(3d,4567.89); // false
Лучший способ сделать это так:
function isThisActuallyANumber(data){
return ( typeof data === "number" && !isNaN(data) );
}
Я думаю, что всю работу здесь может сделать функция parseFloat. Функция ниже проходит все тесты на этой странице, включая isNumeric(Infinity) == true:
function isNumeric(n) {
return parseFloat(n) == n;
}
Да, я тоже пришел к такому выводу. Мне также очень нравится, как с помощью этого метода обрабатываются массивы; массив с одним значением считается этим значением, но все остальное терпит неудачу: IsNumeric([3]) == true;IsNumeric([]) == false;IsNumeric([3, 4]) == false; Но я полагаю, что это дело вкуса!
function inNumeric(n){
return Number(n).toString() === n;
}
Если n - числовое, Number(n) вернет числовое значение, а toString() вернет его обратно в строку. Но если n не является числовым, Number(n) вернет NaN, поэтому он не будет соответствовать исходному n.
Хотя этот фрагмент кода может решить вопрос, включая объяснение действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос для читателей в будущем, и эти люди могут не знать причины вашего предложения кода. Также постарайтесь не загромождать свой код пояснительными комментариями, так как это снижает удобочитаемость как кода, так и пояснений!
Я считаю, что мой код идеален ...
/**
* @param {string} s
* @return {boolean}
*/
var isNumber = function(s) {
return s.trim()!= = "" && !isNaN(Number(s));
};$('.rsval').bind('keypress', function(e){
var asciiCodeOfNumbers = [48,46, 49, 50, 51, 52, 53, 54, 54, 55, 56, 57];
var keynum = (!window.event) ? e.which : e.keyCode;
var splitn = this.value.split(".");
var decimal = splitn.length;
var precision = splitn[1];
if (decimal == 2 && precision.length >= 2 ) { console.info(precision , 'e'); e.preventDefault(); }
if ( keynum == 46 ){
if (decimal > 2) { e.preventDefault(); }
}
if ($.inArray(keynum, asciiCodeOfNumbers) == -1)
e.preventDefault();
});
Вы можете минимизировать эту функцию разными способами, а также можете реализовать ее с помощью настраиваемого регулярного выражения для отрицательных значений или настраиваемых диаграмм:
$('.number').on('input',function(){
var n=$(this).val().replace(/ /g,'').replace(/\D/g,'');
if (!$.isNumeric(n))
$(this).val(n.slice(0, -1))
else
$(this).val(n)
});
Не нужно использовать дополнительную библиотеку.
const IsNumeric = (...numbers) => {
return numbers.reduce((pre, cur) => pre && !!(cur === 0 || +cur), true);
};
Тест
> IsNumeric(1)
true
> IsNumeric(1,2,3)
true
> IsNumeric(1,2,3,0)
true
> IsNumeric(1,2,3,0,'')
false
> IsNumeric(1,2,3,0,'2')
true
> IsNumeric(1,2,3,0,'200')
true
> IsNumeric(1,2,3,0,'-200')
true
> IsNumeric(1,2,3,0,'-200','.32')
true
Простое и понятное решение, основанное на динамической проверке типов языка:
function IsNumeric (string) {
if (string === ' '.repeat(string.length)){
return false
}
return string - 0 === string * 1
}
если вас не волнуют пробелы, вы можете удалить это "если"
см. тестовые примеры ниже
function IsNumeric (string) {
if (string === ' '.repeat(string.length)){
return false
}
return string - 0 === string * 1
}
console.info('-1' + ' → ' + IsNumeric('-1'))
console.info('-1.5' + ' → ' + IsNumeric('-1.5'))
console.info('0' + ' → ' + IsNumeric('0'))
console.info('0.42' + ' → ' + IsNumeric('0.42'))
console.info('.42' + ' → ' + IsNumeric('.42'))
console.info('99,999' + ' → ' + IsNumeric('99,999'))
console.info('0x89f' + ' → ' + IsNumeric('0x89f'))
console.info('#abcdef' + ' → ' + IsNumeric('#abcdef'))
console.info('1.2.3' + ' → ' + IsNumeric('1.2.3'))
console.info('' + ' → ' + IsNumeric(''))
console.info('33 ' + ' → ' + IsNumeric('33 '))function isNumeric(x) {
return parseFloat(x) == x;
}
Тестовые примеры из вопроса:
console.info('trues');
console.info(isNumeric('-1'));
console.info(isNumeric('-1.5'));
console.info(isNumeric('0'));
console.info(isNumeric('0.42'));
console.info(isNumeric('.42'));
console.info('falses');
console.info(isNumeric('99,999'));
console.info(isNumeric('0x89f'));
console.info(isNumeric('#abcdef'));
console.info(isNumeric('1.2.3'));
console.info(isNumeric(''));
console.info(isNumeric('blah'));
Еще несколько тестовых примеров:
console.info('trues');
console.info(isNumeric(0));
console.info(isNumeric(-1));
console.info(isNumeric(-500));
console.info(isNumeric(15000));
console.info(isNumeric(0.35));
console.info(isNumeric(-10.35));
console.info(isNumeric(2.534e25));
console.info(isNumeric('2.534e25'));
console.info(isNumeric('52334'));
console.info(isNumeric('-234'));
console.info(isNumeric(Infinity));
console.info(isNumeric(-Infinity));
console.info(isNumeric('Infinity'));
console.info(isNumeric('-Infinity'));
console.info('falses');
console.info(isNumeric(NaN));
console.info(isNumeric({}));
console.info(isNumeric([]));
console.info(isNumeric(''));
console.info(isNumeric('one'));
console.info(isNumeric(true));
console.info(isNumeric(false));
console.info(isNumeric());
console.info(isNumeric(undefined));
console.info(isNumeric(null));
console.info(isNumeric('-234aa'));
Обратите внимание, что он считает бесконечность числом.
Просто примечание 99 999 - допустимое число во Франции, то же самое, что 99.999 в формате uk / us, поэтому, если вы читаете строку, скажем, из формы ввода, тогда 99 999 может быть истинным.