Javascript 为什么JS中的isNaN(null)==false?
JS中的这段代码给了我一个弹出窗口,上面写着“我认为null是一个数字”,我觉得这有点令人不安。我错过了什么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实际上是
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]