在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
function isNumber(n) {
return (n===n+''||n===n-0) && n*0==0 && /\S/.test(n);
}
解释:
(n===n-0||n===n+'')验证n是数字还是字符串(丢弃数组、布尔值、日期、空值…)。您可以用n替换(n===n-0|| n===n+'')==未定义&&n==null&&(n.constructor==数字||n.constructor==字符串):明显更快,但不那么简洁。
n*0==0验证n是否是有限数,正如isFinite(n)所做的那样。如果您需要检查表示负十六进制的字符串,只需将n*0==0替换为类似于n.toString().replace(/^\s*-/,'')*0==0。当然,它需要一点钱,所以如果你不需要它,就不要使用它。
/\S/.test(n)丢弃空字符串或只包含空格的字符串(这是必要的,因为在这种情况下isFinite(n)或n*0==0返回假阳性)。您可以使用(n!=0||/0/.test(n))而不是\\S/.test(n)来减少对.test(n)的调用次数,也可以使用稍快但不太简洁的测试,例如(n!=0 | |(n+'').indexOf('0')>=0):微小的改进。
如果您希望让数值函数的预测值隐式严格(例如,不解析字符串),那么这应该会奏效。
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()。