为什么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 = nullnull被转换为数字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。 这些是undefinedtypes,typesnumber (但只有值NaN ),任何对象的基本表示forms为NaN ,以及任何不能被parsing的string 。 这留下了undefinedNaNnew 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