validationJavaScript中的十进制数 – IsNumeric()

什么是最简洁,最有效的方法来validationJavaScript中的十进制数字?

奖励积分为:

  1. 明晰。 解决scheme应该干净简单。
  2. 跨平台。

testing用例:

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 

@ Joel的回答非常接近,但在以下情况下会失败:

 // 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函数,以查明一个variables是否包含一个数值, 不pipe它的types如何 ,它可能是一个包含数值的String (我也必须考虑指数表示法等), Number对象,事实上任何东西都可以传递给这个函数,我不能做任何types的假设,照顾types的强制(例如+true == 1;但是不应该被认为是"numeric" )。

我认为值得与众多function实现共享这套+30unit testing ( 旧链接 ),并共享通过我所有的testing:

 function isNumeric(n) { return !isNaN(parseFloat(n)) && isFinite(n); } 

PS 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; } 

更新 : Angular 4.3 :

 export function isNumeric(value: any): boolean { return !isNaN(value - parseFloat(value)); } 

Arrrgh! 不要听正则expression式的答案。 RegEx是这样的,我不是只说性能。 用你的正则expression式很容易做出微妙的,不可能发现的错误。

如果你不能使用isNaN() ,这应该工作得更好:

 function IsNumeric(input) { return (input - 0) == input && (''+input).trim().length > 0; } 

这是如何工作的:

(input - 0)expression式强制JavaScript对input值进行types强制转换; 它必须首先被解释为减法操作的一个数字。 如果转换为数字失败,expression式将导致NaN 。 然后将该数字结果与您传入的原始值进行比较。由于左侧现在是数字,因此再次使用types强制转换。 现在,双方的投入被强制为相同的原始价值相同的types,你会认为他们应该永远是相同的(总是如此)。 然而,有一个特殊的规则说, NaN永远不等于NaN ,所以一个不能转换为数字的值(只有不能转换为数字的值)将会导致错误。

长度检查是针对涉及空string的特殊情况。 另外请注意,它落在你的0x89ftesting,但这是因为在许多环境中,这是一个好方法来定义数字文字。 如果你想抓住特定的情况,你可以添加一个额外的支票。 更好的是,如果这是你不使用isNaN()原因,那么只需将自己的函数包装在isNaN() ,也可以执行额外的检查。

总之, 如果你想知道一个值是否可以转换成一个数字,实际上试着把它转换成一个数字。


我回去做了一些研究, 为什么一个空白string没有预期的输出,我想我现在得到它:一个空string被强制为0而不是NaN 。 在长度检查之前简单地修剪string将处理这种情况。

对新的代码运行unit testing,它只能在无穷大和布尔文本上失败,唯一的问题是如果你正在生成代码(真的,谁会input一个文字并检查它是否是数字?你应该知道 ),这将是一些奇怪的代码来生成。

但是,再次, 使用这个唯一的理由是,如果由于某种原因,你必须避免isNaN()。

这种方式似乎运作良好:

 function IsNumeric(input){ var RE = /^-{0,1}\d*\.{0,1}\d+$/; return (RE.test(input)); } 

并testing它:

 // alert(TestIsNumeric()); 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; } 

我从http://www.codetoad.com/javascript/isnumeric.asp中借用了这个正则expression式。; 说明:

 /^ 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 
 function IsNumeric(num) { return (num >=0 || num < 0); } 

这也适用于0x23types的数字。

雅虎 UI使用这个:

 isNumber: function(o) { return typeof o === 'number' && isFinite(o); } 

被接受的答案不及格#7,我想这是因为你改变了主意。 所以这是对我接受的答案的答复,我有问题。

在一些项目中,我需要validation一些数据,尽可能确定它是一个可以在math运算中使用的javascript数值。

jQuery和其他一些JavaScript库已经包含这样一个函数,通常称为isNumeric。 在stackoverflow上也有一个post ,被广泛接受为答案,就是前面提到的库使用的一样的一般程序。

 function isNumber(n) { return !isNaN(parseFloat(n)) && isFinite(n); } 

首先,如果参数是一个长度为1的数组,则上面的代码将返回true,并且该单个元素的types被上述逻辑视为数字。 在我看来,如果它是一个数组,那么它不是数字。

为了缓解这个问题,我添加了一个检查来从逻辑中折扣数组

 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]'

我的第二个问题是负hex整数文字string(“-0xA” – > -10)不计算为数字。 但是,正数hex整数文字string(“0xA” – > 10)被视为数字。 我需要两个是有效的数字。

然后我修改了逻辑来考虑这一点。

 function isNumber(n) { return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, '')); } 

如果你担心在每次调用函数时创build正则expression式,那么你可以在闭包中重写它,像这样

 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 + 30testing用例,并克隆了jsfiddle上的testing,添加了我的额外testing用例和我上面描述的解决scheme。

它可能不会取代广泛接受/使用的答案,但如果这更多的是你所期望的作为你的isNumeric函数的结果,那么希望这将有一定的帮助。

编辑:正如Bergi指出的,还有其他可能的对象,可以被认为是数字,它会比黑名单更好的白名单。 考虑到这一点,我会添加到标准。

我想我的数字函数只考虑数字或string

考虑到这一点,最好使用它

 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(/^-/, '')); } 

testing解决scheme

 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> 

是的,内置的isNaN(object)比任何正则expression式parsing要快得多,因为它是内置和编译的,而不是实时解释。

尽pipe结果与你正在寻找的东西有些不同( 尝试它 ):

  // 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 

使用函数isNaN 。 我相信,如果你testing!isNaN(yourstringhere)它适用于任何这些情况。

由于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是一个有效的数字(hexa)

这可以不用RegExp来完成

 function IsNumeric(data){ return parseFloat(data)==data; } 

对我来说,这是最好的方法:

 isNumber : function(v){ return typeof v === 'number' && isFinite(v); } 
 return (input - 0) == input && input.length > 0; 

没有为我工作。 当我提醒并testing时, input.length是'undefined'。 我认为没有属性来检查整数长度。 所以我做了什么

 var temp = '' + input; return (input - 0) == input && temp.length > 0; 

它工作正常。

如果我没有弄错,这应该匹配任何有效的JavaScript数值,不包括常数( InfinityNaN )和符号运算符+ / - (因为就我而言,它们实际上并不是数字的一部分,它们是独立的运算符):

我需要一个标记器,在那里发送数字到JavaScript进行评估是不是一个选项…这绝对不是最短的正则expression式,但我相信它捕获了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 

整数值可以通过以下方式validation:

 function isNumeric(value) { var bool = isNaN(+value)); bool = bool || (value.indexOf('.') != -1); bool = bool || (value.indexOf(",") != -1); return !bool; }; 

这样更容易,更快! 所有的testing都被检查!

这里有一个改进的版本(可能是最快的方式),而不是确切的jQuery的变体,我真的不知道他们为什么不使用这个:

 function isNumeric(val) { return !isNaN(+val) && isFinite(val); } 

jQuery的版本的缺点是,如果你传递一个string与引导数字和尾随字母,如"123abc" parseFloat | parseInt parseFloat | parseInt将提取数字小数部分并返回123,但是,第二个后卫isFinite无论如何将会失败。 用一元+运算符,它会死在第一个后卫,因为+抛出NaN这样的混合动力:)一点performance,但我认为是一个坚实的语义增益。

我唯一的问题就是@ CMS的答案是排除NaN和Infinity,在许多情况下它们是有用的数字。 检查NaN的一种方法是检查不相等的数字值, NaN != NaN ! 所以真的有3个testing你想处理…

 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是非常接近另一个优雅的答案 ,但处理hex和其他string表示的数字。

我意识到原来的问题没有提到jQuery,但如果你使用jQuery,你可以这样做:

 $.isNumeric(val) 

简单。

https://api.jquery.com/jQuery.isNumeric/ (截至jQuery 1.7)

我的解决scheme

 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; } 

它似乎在任何情况下都有效,但我可能是错的。

这应该工作。 这里提供的一些function是有缺陷的,也应该比这里的其他function更快。

  function isNumeric(n) { var n2 = n; n = parseFloat(n); return (n!='NaN' && n2==n); } 

解释:

创build自己的副本,然后将数字转换为浮点数,然后将自身与原始数字进行比较,如果数字仍然是数字(无论是整数还是浮点数),并且与原始数字相匹配,则表示的确是一个数字。

它适用于数字string以及普通数字。 不适用于hex数字。

警告:使用风险自负,不保证。

我想添加以下内容:

 1. IsNumeric('0x89f') => true 2. IsNumeric('075') => true 

正数hex数字以0x开始,负hex数字以-0x开始。 正数的八位数字以0开始,负数的八位数字以-0开始。 这个大部分已经被提及的考虑,但包括hex和八进制数,科学负面,无穷大,并删除了小数科学(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)); } 

几个testing添加:

 IsNumeric('01.05') => false IsNumeric('1.') => false IsNumeric('.') => false 

我想出了这个:

 function IsNumeric(input) { return /^-?(0|[1-9]\d*|(?=\.))(\.\d+)?$/.test(input); } 

The solution covers:

  • An optional negative sign at the beginning
  • A single zero, or one or more digits not starting with 0, or nothing so long as a period follows
  • A period that is followed by 1 or more numbers

I'm using simpler solution:

 function isNumber(num) { return parseFloat(num).toString() == num } 

None of the answers return false for empty strings, a fix for that…

 function is_numeric(n) { return (n != '' && !isNaN(parseFloat(n)) && isFinite(n)); } 

@CMS' answer : Your snippet failed on whitespace cases on my machine using nodejs. So I combined it with @joel's answer to the following:

 is_float = function(v) { return !isNaN(v) && isFinite(v) && (typeof(v) == 'number' || v.replace(/^\s+|\s+$/g, '').length > 0); } 

I unittested it with those cases that are floats:

 var t = [ 0, 1.2123, '0', '2123.4', -1, '-1', -123.423, '-123.432', 07, 0xad, '07', '0xad' ]; 

and those cases that are no floats (including empty whitespaces and objects / arrays):

  var t = [ 'hallo', [], {}, 'jklsd0', '', "\t", "\n", ' ' ]; 

Everything works as expected here. 也许这有帮助。

Full source code for this can be found here .

The following seems to works fine for many cases:

 function isNumeric(num) { return (num > 0 || num === 0 || num === '0' || num < 0) && num !== true && isFinite(num); } 

This is built on top of this answer (which is for this answer too): https://stackoverflow.com/a/1561597/1985601

I realize this has been answered many times, but the following is a decent candidate which can be useful in some scenarios.

it should be noted that it assumes that '.42' is NOT a number, and '4.' is NOT a number, so this should be taken into account.

 function isDecimal(x) { return '' + x === '' + +x; } function isInteger(x) { return '' + x === '' + parseInt(x); } 

The isDecimal passes the following test:

 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'); } 

The idea here is that every number or integer has one "canonical" string representation, and every non-canonical representation should be rejected. So we cast to a number and back, and see if the result is the original string.

Whether these functions are useful for you depends on the use case. One feature is that distinct strings represent distinct numbers (if both pass the isNumber() test).

This is relevant eg for numbers as object property names.

 var obj = {}; obj['4'] = 'canonical 4'; obj['04'] = 'alias of 4'; obj[4]; // prints 'canonical 4' to the console. 

knockoutJs Inbuild library validation functions

By extending it the field get validated

1) number

self.number = ko.observable(numberValue) .extend({ number: true}) ;

TestCase

 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) digit

self.number = ko.observable(numberValue) .extend({ digit: true}) ;

TestCase

 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) min and max

self.number = ko.observable(numberValue) .extend({ min: 5}).extend({ max: 10}) ;

This field accept value between 5 and 10 only

TestCase

 numberValue = '5' --> true numberValue = '6' --> true numberValue = '6.5' --> true numberValue = '9' --> true numberValue = '11' --> false numberValue = '0' --> false numberValue = '' --> false 

To check if a variable contains a valid number and not just a String which looks like a number, Number.isFinite(value) can be used.

This is part of the language since 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 

I think parseFloat function can do all the work here. The function below passes all the tests on this page including isNumeric(Infinity) == true:

 function isNumeric(n) { return parseFloat(n) == n; } 
 function inNumeric(n){ return Number(n)+'' === n; } 

If n is numeric Number(n) will return the numeric value and +'' will turn it back to a string. But if n isn't numeric Number(n) will return NaN so it won't match the original n