在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
这里有一个非常简单的(在Chrome、Firefox和IE中测试):
function isNumeric(x) {
return parseFloat(x) == x;
}
来自问题的测试用例:
console.log('trues');
console.log(isNumeric('-1'));
console.log(isNumeric('-1.5'));
console.log(isNumeric('0'));
console.log(isNumeric('0.42'));
console.log(isNumeric('.42'));
console.log('falses');
console.log(isNumeric('99,999'));
console.log(isNumeric('0x89f'));
console.log(isNumeric('#abcdef'));
console.log(isNumeric('1.2.3'));
console.log(isNumeric(''));
console.log(isNumeric('blah'));
更多测试用例:
console.log('trues');
console.log(isNumeric(0));
console.log(isNumeric(-1));
console.log(isNumeric(-500));
console.log(isNumeric(15000));
console.log(isNumeric(0.35));
console.log(isNumeric(-10.35));
console.log(isNumeric(2.534e25));
console.log(isNumeric('2.534e25'));
console.log(isNumeric('52334'));
console.log(isNumeric('-234'));
console.log(isNumeric(Infinity));
console.log(isNumeric(-Infinity));
console.log(isNumeric('Infinity'));
console.log(isNumeric('-Infinity'));
console.log('falses');
console.log(isNumeric(NaN));
console.log(isNumeric({}));
console.log(isNumeric([]));
console.log(isNumeric(''));
console.log(isNumeric('one'));
console.log(isNumeric(true));
console.log(isNumeric(false));
console.log(isNumeric());
console.log(isNumeric(undefined));
console.log(isNumeric(null));
console.log(isNumeric('-234aa'));
注意,它认为无穷大是一个数。
如果您希望让数值函数的预测值隐式严格(例如,不解析字符串),那么这应该会奏效。
function isNumeric(n, parse) {
var t = typeof(n);
if (parse){
if (t !== 'number' && t !=='string') return false;
return !isNaN(parseFloat(n)) && isFinite(n);
}else{
if (t !== 'number') return false;
return !isNaN(n) && isFinite(n) && !_.isString(n);
}
}
function isInteger(n, parse) {
return isNumeric(n, parse) && n % 1 === 0;
}
function isFloat(n, parse) {
return isNumeric(n, parse) && n % 1 !== 0;
}
如果您希望代码解析字符串,那么只需在parse参数中传递true即可。
这是对下划线contrib方法的修改,该方法隐式宽松,尝试解析字符串,甚至为isNumeric([1])返回true,这可能是人们真正的陷阱。我上面的方法也会更快,因为它只在parse=true时调用parseFloat()。
我意识到这一点已经得到了多次回答,但以下是一个不错的人选,在某些情况下可能有用。
需要注意的是,它假设‘.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.
@CMS的回答:您的代码段在我的机器上使用nodejs处理空白情况时失败。所以我把它和@joel对以下问题的回答:
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",
' '
];
这里的一切都按预期进行。也许这有帮助。
这里可以找到完整的源代码。