Javascript 为什么JS中的isNaN(null)==false?

Javascript 为什么JS中的isNaN(null)==false?,javascript,Javascript,JS中的这段代码给了我一个弹出窗口,上面写着“我认为null是一个数字”,我觉得这有点令人不安。我错过了什么 if(isNaN(null)){ 警报(“null不是数字”); }否则{ 警惕(“我认为null是一个数字”); }Null不是NaN,字符串也不是NaN。isNaN()只需测试您是否真的拥有NaN对象。对于JS,我不太确定,但我在其他语言中也看到过类似的情况,这通常是因为函数只检查null是否完全等于NaN(即null==NaN将为false)。换句话说,它不是认为null实际上是

JS中的这段代码给了我一个弹出窗口,上面写着“我认为null是一个数字”,我觉得这有点令人不安。我错过了什么

if(isNaN(null)){
警报(“null不是数字”);
}否则{
警惕(“我认为null是一个数字”);

}
Null不是NaN,字符串也不是NaN。isNaN()只需测试您是否真的拥有NaN对象。

对于JS,我不太确定,但我在其他语言中也看到过类似的情况,这通常是因为函数只检查null是否完全等于NaN(即null==NaN将为false)。换句话说,它不是认为null实际上是一个数字,而是null不是NaN。这可能是因为两者在JS中的表示方式不同,因此它们不会完全相等,就像9!='9.

我相信代码试图问,“是
x
数字吗?”这里的具体情况是
x=null
。函数
isNaN()
可以用来回答这个问题,但在语义上它是专门指值
NaN
。来自维基百科:

NaN(不是数字)是数字数据类型的值,表示未定义或不可表示的值,特别是在浮点计算中

在大多数情况下,我们认为“is null numeric?”的答案应该是否定的。但是,
isNaN(null)==false在语义上是正确的,因为
null
不是
NaN

以下是算法解释:

函数
isNaN(x)
尝试将传递的参数转换为一个数字(相当于
number(x)
),然后测试该值是否为
NaN
。如果参数无法转换为数字,
number(x)
将返回
NaN
。因此,如果将参数
x
转换为数字导致
NaN
,则返回true;否则,它将返回false

因此,在特定情况下,
x=null
null
被转换为数字0,(尝试计算
number(null)
,并查看它是否返回0,
isNaN(0)
返回false。仅为数字的字符串可以转换为数字,isNaN也会返回false。无法转换为数字的字符串(例如
'abcd'
)将导致
isNaN('abcd')
返回true,特别是因为
number('abcd')
返回
NaN

除了这些明显的边缘情况外,返回NaN(如0/0)的标准数值原因也是如此


至于问题中显示的看似不一致的相等性测试,
NaN
的行为被指定为任何比较
x==NaN
都是假的,而不管其他操作数,包括
NaN
本身。

这确实令人不安。以下是我测试的一组值:

var x = [undefined, NaN, 'blah', 0/0, null, 0, '0', 1, 1/0, -1/0, Number(5)]
它(在Firebug控制台中)评估为:

当我调用
x.map(isNaN)
(对每个值调用isNaN)时,我得到:

总之,
isNaN
看起来毫无用处!(Edit:除了isNaN只定义在数字上,在这种情况下,它工作得很好——只是使用了一个误导性的名称。)

顺便提一下,以下是这些值的类型:

x.map(function(n){return typeof n})
-> undefined,number,string,number,object,number,string,number,number,number,number
(我的另一个评论是从实际出发的。这是理论方面。)

我查找了,这是Javascript实现的。他们对isNan的规格:

将TonNumber应用于其参数,如果结果为NaN,则返回true,否则返回false

第9.3节规定了
ToNumber
(它不是一个可调用函数,而是类型转换系统的一个组件)的行为。为了总结该表,某些输入类型可以生成NaN。它们是类型
未定义
、类型
编号
(但仅值
NaN
)、其基本表示形式为
NaN
的任何对象以及无法解析的任何
字符串。这使得
未定义
NaN
新编号(NaN)
,以及大多数字符串

当传递到
ToNumber
时产生
NaN
作为输出的任何此类输入将在馈送到
isNaN
时产生
true
。由于
null
可以成功转换为数字,因此它不会生成
true

这就是为什么。

注意:

"1" == 1 // true
"1" === 1 // false
==运算符进行类型转换,而===不进行类型转换


雅虎!JavaScript evangelist是此类内容的一个很好的资源。

我自己也遇到过这个问题

对我来说,使用isNaN的最好方法就是这样

isNaN(parseInt(myInt))

以上面的phyzome为例

var x = [undefined, NaN,     'blah', 0/0,  null, 0,     '0',   1,     1/0, -1/0,  Number(5)]
x.map( function(n){ return isNaN(parseInt(n))})
        [true,      true,    true,   true, true, false, false, false, true, true, false]
(我根据输入对齐了结果,希望它更容易阅读。)


我觉得这样更好

在ES5中,它被定义为
isNaN(number)
如果参数强制为NaN,则返回true,否则返回false

  • 如果为NaN,则返回true
  • 否则,返回false

看看这个。所以它在内部计算
tonnumber(Null)
+0
,然后最终
isNaN(Null)
false

你的意思不是“为什么isNaN(Null)==false”?根据你的代码,isNaN(Null)返回false(Null不是一个数字),如果它说“我认为Null是一个数字”。但至少会将一个字符串强制转换为NaN对象,因为isNaN(“text”)返回true.BTW,
NaN!==NaN
。因此,我认为说
Number('abcd')==NaN是不完全正确的,因为
Number('abcd')
NaN
,但不等于
NaN
。我喜欢JavaScript。是的。我的意思是说
Number('abcd')
NaN
,但我暗示它测试的是是否相等,事实并非如此。我会编辑它。我想知道为什么
isNaN
Number
设计成这样的行为
"1" == 1 // true
"1" === 1 // false
var x = [undefined, NaN,     'blah', 0/0,  null, 0,     '0',   1,     1/0, -1/0,  Number(5)]
x.map( function(n){ return isNaN(parseInt(n))})
        [true,      true,    true,   true, true, false, false, false, true, true, false]