JS中的这段代码给了我一个弹出窗口“我认为null是一个数字”,我觉得有点令人不安。我错过了什么?
if (isNaN(null)) {
alert("null is not a number");
} else {
alert("i think null is a number");
}
我正在使用Firefox 3.这是一个浏览器错误吗?
其他测试:
null == NaN; // false
isNaN("text"); // true
NaN == "text" // false
那么,问题似乎不是与NaN的精确比较?
编辑:现在问题已经回答了,我已经清理了我的帖子,以便为存档提供更好的版本。然而,这使得一些评论甚至一些答案有点难以理解。不要责怪他们的作者。我改变的是:
的答案 0 :(得分:101)
我相信代码试图问,“x
是数字吗?”这里的具体案例为x = null
。函数isNaN()
可用于回答此问题,但从语义上讲,它特指值NaN
。来自维基百科NaN
:
NaN( N ot a N umber)是表示未定义或不可表示的值的数值数据类型的值,尤其是在浮动时点计算。
在大多数情况下,我们认为“无效数字”的答案是什么?应该是没有。但是,isNaN(null) == false
在语义上是正确的,因为null
不是NaN
。
以下是算法解释:
函数isNaN(x)
尝试将传递的参数转换为数字 1 (相当于Number(x)
),然后测试值是否为{{1 }}。如果参数无法转换为数字,NaN
将返回Number(x)
2 。因此,如果将参数NaN
转换为数字会导致x
,则返回true;否则,它返回false。
因此,在特定情况NaN
中,x = null
转换为数字0,(尝试评估null
并看到它返回0,)并且Number(null)
返回false 。只有数字的字符串可以转换为数字,而isNaN也返回false。无法转换为数字的字符串(例如isNaN(0)
)会导致'abcd'
返回true,特别是因为isNaN('abcd')
返回Number('abcd')
。
除了这些明显的边缘情况之外,返回NaN的标准数值原因如0/0。
对于问题中显示的看似不一致的相等性测试,NaN
的行为被指定为任何比较NaN
都是假的,无论其他操作数如何,包括x == NaN
本身 1
答案 1 :(得分:20)
我自己也遇到了这个问题。
对我来说,使用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]
(我根据输入对齐结果,希望它更容易阅读。)
这对我来说似乎更好。
答案 2 :(得分:7)
这确实令人不安。这是我测试的一系列值:
var x = [undefined, NaN, 'blah', 0/0, null, 0, '0', 1, 1/0, -1/0, Number(5)]
它评估(在Firebug控制台中):
,NaN,blah,NaN,,0,0,1,Infinity,-Infinity,5
当我拨打x.map(isNaN)
(在每个值上调用isNaN)时,我得到:
true,true,true,true,false,false,false,false,false,false,false
总之,isNaN
看起来很无用! (编辑:除非事实证明isNaN只是已定义而不是数字,在这种情况下它的工作正常 - 只是带有误导性的名称。)
顺便提一下,以下是这些值的类型:
x.map(function(n){return typeof n})
-> undefined,number,string,number,object,number,string,number,number,number,number
答案 3 :(得分:7)
(我的另一个评论采用了实用的方法。这是理论方面。)
我查找了ECMA 262 standard,这是Javascript实现的。他们对isNan的规范:
将ToNumber应用于其参数,如果结果为NaN则返回true,否则返回false。
9.3节指定ToNumber
的行为(它不是可调用函数,而是类型转换系统的一个组件)。总结该表,某些输入类型可以产生NaN。这些是类型undefined
,类型number
(但只有值NaN
),其基本表示为NaN
的任何对象,以及任何无法解析的string
。这会留下undefined
,NaN
,new Number(NaN)
和大多数字符串。
传递给NaN
时产生ToNumber
作为输出的任何此类输入在输入true
时将产生isNaN
。由于null
可以成功转换为数字,因此不会生成true
。
这就是原因。
答案 4 :(得分:5)
Null不是NaN,字符串也不是NaN。 isNaN()只测试你是否真的有NaN对象。
答案 5 :(得分:1)
我不确定JS是什么,但我在其他语言中看到了类似的东西,通常是因为该函数只检查null是否与NaN完全相等(即null === NaN将为false )。换句话说,它不是认为null实际上是一个数字,而是null而不是NaN。这可能是因为两者在JS中的表示方式不同,因此它们不会完全相同,就像9!=='9'一样。
答案 6 :(得分:1)
在ES5中,如果参数强制转换为NaN,则定义为isNaN (number)
返回true,否则返回false。
并查看The abstract operation ToNumber convertion table。因此内部js引擎评估ToNumber(Null)
为+0
,最后isNaN(null)
为false
答案 7 :(得分:0)
注意:
"1" == 1 // true
"1" === 1 // false
==运算符执行类型转换,而===则不执行。
Douglas Crockford's website,雅虎! JavaScript传播者,对于像这样的东西来说是一个很好的资源。
答案 8 :(得分:-1)
(NaN == null) // false
(NaN != null) // true
虽然很有趣:
(NaN == true) // false
(NaN == false) // false
(NaN) // false
(!NaN) // true
(NaN == false)
和 (!NaN)
不是一样的吗?