Javascript 为什么isNaN(带空格的字符串)等于false?
在JavaScript中,为什么Javascript 为什么isNaN(带空格的字符串)等于false?,javascript,nan,Javascript,Nan,在JavaScript中,为什么isNaN(“”求值为false,而isNaN(“x”)求值为true 我正在对文本输入字段执行数字操作,并检查该字段是否为null、“”或NaN。当有人在字段中键入少量空格时,我的验证在这三个字段上都失败了,我不明白为什么它会通过isNaN检查。JavaScript将空字符串解释为0,然后使isNaN测试失败。可以首先对字符串使用parseInt,这不会将空字符串转换为0。然后,结果将失败。尝试使用: alert(isNaN(parseInt(" ")));
isNaN(“”
求值为false
,而isNaN(“x”)
求值为true
我正在对文本输入字段执行数字操作,并检查该字段是否为
null
、“
”或NaN
。当有人在字段中键入少量空格时,我的验证在这三个字段上都失败了,我不明白为什么它会通过isNaN
检查。JavaScript将空字符串解释为0,然后使isNaN测试失败。可以首先对字符串使用parseInt,这不会将空字符串转换为0。然后,结果将失败。尝试使用:
alert(isNaN(parseInt(" ")));
或
我认为这是因为Javascript的键入:
'
被转换为零,而'x'
不是:
alert(' ' * 1); // 0
alert('x' * 1); // NaN
我不知道为什么,但是为了避免这个问题,你可以在检查之前删掉空格。您可能还是想这样做。要更好地理解它,请打开第43页的“应用于字符串类型的ToNumber” 如果字符串具有数字语法(可以包含任意数量的空格字符),则可以将其转换为数字类型。空字符串的计算结果为0。字符串“Infinity”也应该给出
isNaN('Infinity'); // false
您可能会感到惊讶,也可能不会,但这里有一些测试代码向您展示JavaScript引擎的古怪之处
document.write(isNaN("")) // false
document.write(isNaN(" ")) // false
document.write(isNaN(0)) // false
document.write(isNaN(null)) // false
document.write(isNaN(false)) // false
document.write("" == false) // true
document.write("" == 0) // true
document.write(" " == 0) // true
document.write(" " == false) // true
document.write(0 == false) // true
document.write(" " == "") // false
这意味着
" " == 0 == false
及
但是
玩得开心:)如果你想实现一个精确的isNumber函数,这里有一种通过Javascript实现的方法:Douglas Crockford的《好的部分》[第105页]
var isNumber = function isNumber(value) {
return typeof value === 'number' &&
isFinite(value);
}
如果您确实想要正确检查它是否为整数,我建议您使用以下函数:
function isInteger(s)
{
return Math.ceil(s) == Math.floor(s);
}
这个函数在我的测试中似乎起作用
function isNumber(s) {
if (s === "" || s === null) {
return false;
} else {
var number = parseInt(s);
if (number == 'NaN') {
return false;
} else {
return true;
}
}
}
那怎么办
function isNumberRegex(value) {
var pattern = /^[-+]?\d*\.?\d*$/i;
var match = value.match(pattern);
return value.length > 0 && match != null;
}
函数isNaN(“”)
执行字符串到数字类型强制
- 未定义
- 对象(空、对象、数组)
- 布尔值
- 数
- 串
- 作用
function isNumber (s) {
return typeof s == 'number'? true
: typeof s == 'string'? (s.trim() === ''? false : !isNaN(s))
: (typeof s).match(/object|function/)? false
: !isNaN(s)
}
此函数的目的不是测试变量类型,而是测试强制值。例如,布尔和字符串被强制为数字,因此您可能希望将此函数调用为isNumberCoerced()
如果不需要测试字符串和数字以外的类型,则以下代码段可能会用作某些条件的一部分:
if (!isNaN(s) && s.toString().trim()!='') // 's' can be boolean, number or string
alert("s is a number")
isNaN(“”
为false是isNaN
全局函数混乱行为的一部分,因为它将非数字强制为数字类型
发件人:
自从最早版本的isNaN
函数规范以来,它对非数值参数的行为一直令人困惑。当isNaN
函数的参数不是Number类型时,该值首先强制为一个数字。然后测试结果值以确定其是否为NaN
。因此,对于强制为数字类型时产生有效非NaN数值的非数字(尤其是空字符串和布尔基元,强制时给出数值零或一),“false”返回值可能是意外的;例如,空字符串肯定是“不是数字”
还要注意,对于ECMAScript 6,现在还有Number.isNaN
方法,根据MDN:
与全局isNaN()
函数相比,Number.isNaN()
不会遇到将参数强制转换为数字的问题。这意味着现在可以安全地传递通常转换为NaN
,但实际上与NaN
的值不同的值。这也意味着只有类型编号的值(也是NaN
)返回true
不幸的是:
甚至ECMAScript 6Number.isNaN
方法也有它自己的问题,正如在博客文章中所概述的-。来自您所面临问题的原因
当isNaN函数的参数不是Number类型时,该值首先强制为一个数字。然后测试结果值以确定其是否为NaN
您可能需要检查以下综合答案,其中也包括NaN的平等性比较
isNaN
函数需要一个数字作为其参数,因此在执行实际函数逻辑之前,任何其他类型的参数(在本例中为字符串)都将转换为数字。(请注意,NaN
也是类型Number的值!)
顺便说一句,这在所有内置函数中都很常见-如果它们需要某个类型的参数,那么实际参数将使用标准转换函数进行转换。所有基本类型(bool、string、number、object、date、null、undefined)之间都有标准转换
可以使用Number()
显式调用String
到Number
的标准转换。因此,我们可以看到:
的计算结果为Number(“”
0
的计算结果为Number(“x”)
NaN
isNaN
函数的结果完全符合逻辑
真正的问题是,为什么标准字符串到数字的转换会像它那样工作。字符串到数字的转换实际上是为了将数字字符串(如“123”或“17.5e4”)转换为等效的数字。转换首先跳过初始空白(因此“123”是有效的),然后尝试将其余部分解析为数字。如果不能解析为数字(“x”不是),则结果为NaN。但有一个明确的特殊规则,即空字符串或只有空格的字符串被转换为0。这就是转换的原因
参考资料:我编写了这个快速的小函数来帮助解决这个问题
function isNumberRegex(value) {
var pattern = /^[-+]?\d*\.?\d*$/i;
var match = value.match(pattern);
return value.length > 0 && match != null;
}
function isNumber (s) {
return typeof s == 'number'? true
: typeof s == 'string'? (s.trim() === ''? false : !isNaN(s))
: (typeof s).match(/object|function/)? false
: !isNaN(s)
}
if (!isNaN(s) && s.toString().trim()!='') // 's' can be boolean, number or string
alert("s is a number")
function isNumber(val) {
return (val != undefined && val != null && val.toString().length > 0 && val.toString().match(/[^0-9\.\-]/g) == null);
};
function isNaNDemo(arg){
var x = new Number(arg).valueOf();
return x != x;
}
function isNaNstatic(x){
return x != x;
}
isNaN(123) //false
isNaN(-1.23) //false
isNaN(5-2) //false
isNaN(0) //false
isNaN('123') //false
isNaN('Hello') //true
isNaN('2005/12/12') //true
isNaN('') //false
isNaN(true) //false
isNaN(undefined) //true
isNaN('NaN') //true
isNaN(NaN) //true
isNaN(0 / 0) //true
1. Let num be ToNumber(number).
2. ReturnIfAbrupt(num).
3. If num is NaN, return true.
4. Otherwise, return false.
Number(" ") // 0
Number("x") // NaN
Number(null) // 0
Object.assign(Number.prototype, {
isNumericallyValid(num) {
if (
num === null
|| typeof num === 'boolean'
|| num === ''
|| Number.isNaN(Number(num))
) {
return false;
}
return true;
}
});