Number.IsNaN() 是否比 isNaN() 更坏

IT技术 javascript nan ecmascript-6
2021-03-16 19:37:30

SoooooooisNaN显然在 JavaScript 中被破坏了,例如:

isNaN('')
isNaN('   ')
isNaN(true)
isNaN(false)
isNaN([0])

返回 false,当它们看起来都是......不是数字......

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

我希望

Number.isNaN('RAWRRR')

返回true,因为它是一个字符串,不能转换为数字......但是......

在此处输入图片说明

看来我会考虑的事情……不是数字,确实,不是,不是数字……

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

MDN 上的例子说:

Number.isNaN("blabla"); // 例如这对 isNaN 来说是正确的

我不明白这是“原始全局 isNaN 的更强大版本”。当我无法检查事物是否不是数字时。

这意味着我们仍然需要进行实际的类型检查以及检查 isNaN ......这似乎很愚蠢......

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

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

有没有其他人发现这被破坏了,或者我只是不理解 isNaN 的意义?

6个回答

isNaN()并且Number.isNaN()两者都测试一个值是否是(或者,在 的情况下isNaN(),可以转换为表示的数字类型值)该NaN值。换句话说,“NaN”并不仅仅意味着“这个值不是一个数字”,它特指“这个值是一个符合 IEEE-754数字Not-a-Number 值”。

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

Number('')    // 0
Number('   ') // 0
Number(true)  // 1
Number(false) // 0
Number([0])   // 0

原因isNaN()是“损坏”,表面上看,在测试值时不应该发生类型转换。这就是Number.isNaN()旨在解决的问题特别是,如果该值是数字类型值Number.isNaN()只会尝试将值与NaN该值进行比较任何其他类型都将返回 false,即使它们实际上是“不是数字”,因为类型NaN是数字。有关isNaN()和 ,请参阅相应的 MDN 文档Number.isNaN()

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

typeof 'RAWRRR' === 'number' // false
@d512:仅仅因为您个人没有用于检查值是否为 NaN 的用例,并不会使它成为一个糟糕的算法或损坏。也许您可以提议添加 Number.isNumeric() 函数,但如果没有人这样做我会感到惊讶。
2021-04-28 19:37:30
@ d512 显然你不理解这个答案,因为重点是它isNaN 没有被“破坏”。它不是检查值是否为数字(您可以使用parseInt或 jQuery$.isNumeric来执行此操作)-isNaN实际上是检查值是否为NaN,这是在 JavaScript 中具有非常特定含义的特殊值。
2021-05-05 19:37:30
令人沮丧的是,他们引入了另一种方法来检查以许多相同方式损坏的 NaN(以及一些新的启动方式)。
2021-05-09 19:37:30
我会推荐:typeof value === 'number' && !isNaN(value)因为typeof NaN === 'number'
2021-05-15 19:37:30
迄今为止我见过的最清晰的解释。
2021-05-20 19:37:30

不行,原件isNaN坏了。你没有理解isNaN.

这两个函数的目的是确定某物是否具有valueNaN之所以提供此信息,是因为something === NaN将始终存在false,因此不能用于对此进行测试。(旁注:something !== something实际上是一个可靠的,虽然违反直觉的测试NaN

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

所以

isNaN("hello")

true,即使"hello"不是NaN

如果你想检查一个值是否真的是一个有限数,你可以使用:

Number.isFinite(value)

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

Number.isFinite(value) || (Number.isFinite(Number(value)) && typeof value === 'string')
不完全:Number.isFinite(parseFloat('1f'))返回true
2021-04-22 19:37:30
@GabrielFlorit 你是对的。我想我现在已经解决了。
2021-04-26 19:37:30
很好的解释
2021-05-18 19:37:30

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

isNaN("blabla") === true

因为Number("blabla")结果NaN

这里有两个“非数字”的定义,这可能是混淆所在。Number.isNaN(x)仅对 IEEE 754 浮点规范的 Not a Number 定义返回 true,例如:

Number.isNaN(Math.sqrt(-1))

与确定传入的对象是否为数字类型相反。这样做的一些方法是:

typeof x === "number"
x === +x
Object.prototype.toString.call(x) === "[object Number]"

如评论中所述isNaN()Number.isNaN()两者都检查您传入的值是否不等于 value NaN这里的关键是它NaN是一个实际值而不是一个评估结果,例如"blabla"是 aString并且值是"blabla"这意味着它不是值"NaN"

一个合理的解决方案是做类似的事情:

Number.isNaN(Number("blabla")); //returns true.
您的解决方案在Number.isNaN(Number(" ")).
2021-04-27 19:37:30
@JLRishe 其他可能性:const someValue = <anything>; !isNaN(+someValue)const someValue = <anything>; !isNaN(parseFloat(someValue))
2021-05-02 19:37:30

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

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

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

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

~快乐编码!