Number.IsNaN()比isNaN()更破碎

Phi*_*ill 52 javascript nan ecmascript-6

Soooooo isNaN显然在JavaScript中被打破了,例如:

isNaN('')
isNaN('   ')
isNaN(true)
isNaN(false)
isNaN([0])
Run Code Online (Sandbox Code Playgroud)

回归假,当他们看起来都是......不是数字......

在ECMAScript 6中,草案包含一个新的,Number.isNaN但看起来像(imo)这也被打破了......

我期待

Number.isNaN('RAWRRR')
Run Code Online (Sandbox Code Playgroud)

要返回true,因为它是一个字符串,并且无法转换为数字...但是......

在此输入图像描述

似乎我会考虑的事情......不是数字,确实不是,不是数字......

http://people.mozilla.org/~jorendorff/es6-draft.html#sec-isfinite-number

MDN的例子说:

Number.isNaN( "布拉布拉"); //例如,isNaN就是这样

我不明白这是怎样的"原始全球isNaN的更强大的版本." 当我无法检查,看看事情是不是一个数字.

这意味着我们仍然需要进行实际的类型检查以及检查isNaN ...这看起来很傻......

http://people.mozilla.org/~jorendorff/es6-draft.html#sec-isnan-number

这里的ES3草案基本上说,一切都是假的,除了它的Number.NaN

有没有人发现这个坏了或者我只是不明白isNaN的意思?

Bol*_*ock 92

isNaN()并且Number.isNaN()两者都测试一个值是否(或者,在这种情况下isNaN(),可以转换为表示的数字类型值)该NaN值.换句话说,"NaN"不仅仅意味着"该值不是数字",它具体表示"该值是根据IEEE-754 的数字非数字值".

上面所有测试返回false的原因是因为所有给定的值都可以转换为不是的数值NaN:

Number('')    // 0
Number('   ') // 0
Number(true)  // 1
Number(false) // 0
Number([0])   // 0
Run Code Online (Sandbox Code Playgroud)

原因isNaN()是"破坏"是因为,表面上看,在测试值时不应该发生类型转换.这是该问题Number.isNaN()旨在解决的问题.特别是,如果值是数字类型值,Number.isNaN()尝试比较NaN值.任何其他类型都将返回false,即使它们字面上"不是数字",因为值的类型NaN是数字.请参见相应的MDN文档的isNaN()Number.isNaN().

如果您只想确定某个值是否为数字类型,即使该值是NaN,请typeof改为使用:

typeof 'RAWRRR' === 'number' // false
Run Code Online (Sandbox Code Playgroud)

  • 到目前为止我见过的最清晰的解释. (4认同)
  • 我建议:`typeof value ==='number'&&!isNaN(value)`.因为`typeof NaN ==='number'`. (4认同)
  • @ d512显然你不明白这个答案,因为整个观点是`isNaN` _isn't_"broken".它不是检查值是否为数字(您可以使用`parseInt`或jQuery的`$ .isNumeric`来执行此操作) - `isNaN`实际上是检查值是否为'NaN`,这是一个特殊值,带有JavaScript中非常具体的含义. (3认同)
  • @ d512:只是因为你个人没有一个用例来检查一个值是否为NaN不会使它成为一个糟糕的算法,或者是破坏的.也许您可以建议添加Number.isNumeric()函数,但如果没有人这样做,我会感到惊讶. (2认同)

JLR*_*she 19

不,原件isNaN坏了.你不明白这一点isNaN.

这两个函数的目的是确定某些东西是否具有该值NaN.这是因为something === NaN将始终是false因此不能用于测试这一点.(旁注:something !== something实际上是可靠的,虽然反直觉,测试NaN)

原因isNaN是它可以true在实际上没有值的情况下返回NaN.这是因为它首先将值强制转换为数字.

所以

isNaN("hello")
Run Code Online (Sandbox Code Playgroud)

true,即使"hello"是没有NaN.

如果要检查值是否实际为有限数,可以使用:

Number.isFinite(value)
Run Code Online (Sandbox Code Playgroud)

如果要测试值是有限数字还是字符串表示形式,可以使用:

Number.isFinite(value) || (Number.isFinite(Number(value)) && typeof value === 'string')
Run Code Online (Sandbox Code Playgroud)


Tom*_*ech 7

两者之间的关键区别在于全局isNaN(x)函数执行参数x到数字的转换.所以

isNaN("blabla") === true
Run Code Online (Sandbox Code Playgroud)

因为Number("blabla")结果NaN

这里有两个"非数字"的定义,也许是混淆所在的地方.Number.isNaN(x)仅对IEEE 754浮点规范的非数字定义返回true,例如:

Number.isNaN(Math.sqrt(-1))
Run Code Online (Sandbox Code Playgroud)

而不是确定传入的对象是否是数字类型.一些方法是:

typeof x === "number"
x === +x
Object.prototype.toString.call(x) === "[object Number]"
Run Code Online (Sandbox Code Playgroud)


kas*_*rch 5

正如评论中所提到的isNaN(),Number.isNaN()两者都会检查您传入的值是否不等于该值NaN.这里的关键是NaN实际值而不是评估结果,例如"blabla"是a String,值是"blabla"表示它不是值"NaN".

一个看似合理的解决方案可能是这样的:

Number.isNaN(Number("blabla")); //returns true.
Run Code Online (Sandbox Code Playgroud)

  • 你的解决方案在`Number.isNaN(Number(""))`的情况下仍然不起作用. (2认同)

Jac*_*fin 5

基本上,window.isNaN执行到数字的类型转换,然后检查它是否为 NaN。然而,Number.isNaN不会尝试将其参数转换为数字。所以基本上,你可以认为window.isNaNNumber.isNaN是这样工作的。

window.isNaN = function(n){
    return Number(n) !== Number(n);
}

window.Number.isNaN = function(n){
    return n !== n;
}
Run Code Online (Sandbox Code Playgroud)

请注意,您实际上不需要使用window.来调用isNaNNumber.isNaN。相反,我只是用它来更好地区分两个名称相似的方法,以减少混淆。

~ 快乐编码!