为什么JS中的isNaN(null)== false?
在JS中的这个代码给了我一个popup窗口,说“我认为null是一个数字”,我觉得有点令人不安。 我错过了什么?
if (isNaN(null)) { alert("null is not a number"); } else { alert("i think null is a number"); }
我正在使用Firefox 3.这是一个浏览器错误?
其他testing:
null == NaN; // false isNaN("text"); // true NaN == "text" // false
那么,问题似乎不是与NaN的确切比较?
编辑:现在这个问题已经回答了,我已经清理了我的post,为档案有一个更好的版本。 然而,这个提出了一些意见,甚至有些答案有点不可理解。 不要责怪他们的作者。 我改变的事情是:
- 删除了一个说法,说我把头版搞错了,通过回复它的意思
- 早些时候的答案显示,我没有足够清楚地说明为什么我认为这种行为很奇怪,所以我添加了检查string的示例并进行手动比较。
我相信代码试图问,“是数字? 在这里x = null
的具体情况。 函数isNaN()
可以用来回答这个问题,但是在语义上它指的是NaN
的值。 维基百科对于NaN
:
NaN( N不是数字)是表示未定义或不可表示值的数值数据types的值,特别是在浮点计算中。
在大多数情况下,我们认为答案是“是空数字? 应该是没有的。 但是, isNaN(null) == false
在语义上是正确的,因为null
不是NaN
。
algorithm解释如下:
函数isNaN(x)
尝试将传递的参数转换为数字1 (相当于Number(x)
),然后testing该值是否为NaN
。 如果参数不能转换为数字, Number(x)
将返回NaN
2 。 因此,如果将参数x
转换为一个数字导致NaN
,则返回true; 否则,它返回false。
所以在特定情况下x = null
, null
被转换为数字0,(尝试计算Number(null)
并查看它返回0), isNaN(0)
返回false。 只有数字的string可以转换为数字,isNaN也会返回false。 无法转换为数字的string(例如'abcd'
)会导致isNaN('abcd')
返回true,具体原因是Number('abcd')
返回NaN
。
除了这些明显的边缘情况,还有像0/0那样返回NaN的标准数字原因。
至于问题中显示的看起来不一致的等式testing, NaN
的行为被指定为使得任何比较x == NaN
都是false,而不pipe其他操作数,包括NaN
本身1 。
我自己也遇到过这个问题
对我来说,使用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]
(我根据inputalignment结果,希望能更容易阅读。)
这对我来说似乎更好。
(我的其他评论需要一个实用的方法,这里是理论方面。)
我查阅了ECMA 262标准 ,这是Javascript实现的标准。 他们的规范isNan:
将ToNumber应用于其参数,如果结果为NaN则返回true,否则返回false。
9.3节指定了ToNumber
的行为(这不是一个可调用函数,而是types转换系统的一个组件)。 总结表格,某些inputtypes可以产生一个NaN。 这些是undefined
types,typesnumber
(但只有值NaN
),任何对象的基本表示forms为NaN
,以及任何不能被parsing的string
。 这留下了undefined
, NaN
, new Number(NaN)
和大部分string。
当传递给ToNumber
时,任何生成NaN
作为输出的这种input将在input到isNaN
时产生一个true
。 由于null
可以成功转换为数字,因此不会生成true
。
这就是为什么。
这确实令人不安。 这是我testing的一系列值:
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只是定义在数字,在这种情况下,它工作得很好 – 只是一个误导的名字。)
顺便说一句,这里是这些值的types:
x.map(function(n){return typeof n}) -> undefined,number,string,number,object,number,string,number,number,number,number
Null不是NaN,还有一个string不是NaN。 isNaN()只是testing你是否真的有NaN对象。
我不完全确定什么时候谈到JS,但我已经看到了其他语言类似的东西,通常是因为该函数只检查null是否完全等于NaN(即null === NaN将是false)。 换句话说,它不是认为null实际上是一个数字,而是null而不是NaN。 这可能是因为两者在JS中的表示方式不同,所以它们不会完全相同,就像9!=='9'一样。
注意:
"1" == 1 // true "1" === 1 // false
==运算符可以进行types转换,而===不会。
道格拉斯克罗克福德的网站 ,雅虎! JavaScript的传道者,是这样的东西很好的资源。
在ES5中,它被定义为isNaN (number)
如果参数强制为NaN则返回true,否则返回false。
- 如果ToNumber(number)是NaN,则返回true。
- 否则,返回false。
请参阅抽象操作ToNumber转换表 。 所以它内部的js引擎评估ToNumber(Null)
是+0
,那么最终是isNaN(null)
是false