Во время некоторых проектов мне нужно было проверить некоторые данные и быть как можно более уверенными, что это числовое значение 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