Улучшена функция isnumeric()?
Во время некоторых проектов мне нужно было проверить некоторые данные и быть как можно более уверенными, что это числовое значение javascript, которое можно использовать в математических операциях.
jQuery, а некоторые другие библиотеки javascript уже включают такую функцию, обычно называемую isNumeric. Существует также сообщение qaru.site/info/386/..., которое широко признано в качестве ответа, той же общей процедурой, что и используемые вышеупомянутые библиотеки.
function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
Будучи моим первым сообщением, я не смог ответить в этой теме. Проблема, с которой я столкнулась с принятой записью, заключалась в том, что, как представляется, некоторые угловые случаи повлияли на некоторые работы, которые я делал, и поэтому я внесла некоторые изменения, чтобы попытаться охватить проблему, которую я имел.
Во-первых, приведенный выше код вернет true, если аргумент был массивом длины 1, и этот единственный элемент был по типу, считанному в соответствии с указанной выше логикой. На мой взгляд, если это массив, то это не числовое.
Чтобы облегчить эту проблему, я добавил проверку на дисковые массивы из логики
function isNumber(n) {
return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n);
}
Конечно, вы также можете использовать Array.isArray
вместо Object.prototype.toString.call(n) !== '[object Array]'
EDIT: Я изменил код, чтобы отразить общий тест для массива, или вы можете использовать jquery $.isArray
или прототипы Object.isArray
Моя вторая проблема заключалась в том, что Negative Hexadecimal целые литералы ( "-0xA" → -10) не считались числовыми. Однако положительные шестнадцатеричные целые литералы ( "0xA" → 10) воспринимаются как числовые. Мне нужно, чтобы оба были действительными числами.
Затем я изменил логику, чтобы принять это во внимание.
function isNumber(n) {
return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
}
Если вы беспокоитесь о создании регулярного выражения каждый раз, когда вызывается функция, вы можете переписать его в закрытии, что-то вроде этого
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, то, надеюсь, это поможет.
EDIT. Как указано Bergi, есть и другие возможные объекты, которые можно считать числовыми, и было бы лучше, чем белый список черный список. Имея это в виду, я бы добавил к критериям.
Я хочу, чтобы моя функция 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(/^-/, ''));
}
Это было добавлено как тест 22
Ответы
Ответ 1
По-моему, если это массив, то это не числовое. Чтобы облегчить эту проблему, я добавил проверку на дисковые массивы из логики
У вас может быть и проблема с любым другим объектом, например {toString:function(){return "1.2";}}
. Какие объекты вы считаете численными? Number
объектов? Отсутствует?
Вместо того чтобы пытаться занести в черный список некоторые вещи, которые не прошли тест, вы должны явно присваивать белый список тем, что хотите быть числовыми. Какова должна быть ваша функция, примитивные строки и числа? Затем проверьте их точно:
(typeof n == "string" || typeof n == "number")
Ответ 2
Если вам удобно использовать регулярные выражения, это может сделать трюк:
function (n)
{
return (Object.prototype.toString.call(n) === '[object Number]' ||
Object.prototype.toString.call(n) === '[object String]') &&
(typeof(n) != 'undefined') && (n!=null) &&
(/^-?\d+((.\d)?\d*(e[-]?\d)?(\d)*)$/.test(n.toString()) ||
/^-?0x[0-9A-F]+$/.test(n.toString()));
}
edit: исправлена проблема с шестнадцатеричными номерами
Ответ 3
function isNumber(value){return typeof value == 'number';}
Ответ 4
Если AMD вам нравится, посмотрите mout isNumber().
Ответ 5
Как насчет:
function isNumber(value) {
value = Number(value);
return typeof value === 'number' && !isNaN(value) && isFinite(value);
}
Ответ 6
Функция isNaN, используемая для проверки значения, является числовой или нет. Если значения являются числовыми, возвращается значение true else, возвращаемое false.
код:
<script>
function IsNumeric(val) {
if (isNaN(parseFloat(val))) {
return false;
}
return true
}
bool IsNumeric(string);
</script>
Ответ 7
function isNumber(value){
return !isNaN(parseFloat(value)) &&
isFinite(value.toString().replace(/^-/, '')) &&
typeof value !== 'object';
}
или:
function isNumber(value){
return !Array.isArray(value) && !isNaN(parseFloat(value)) &&
isFinite(value.toString().replace(/^-/, '')) &&
Object.prototype.toString.call(value) !== '[object Object]';
}