Улучшена функция 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]';
}