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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25176459/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 04:07:20  来源:igfitidea点击:

Is Number.IsNaN() more broken than isNaN()

javascriptnanecmascript-6

提问by Phill

Soooooo isNaNis apparently broken in JavaScript, with things like:

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

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

Returning false, when they appear to all be... Not a Number...

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

In ECMAScript 6, the draft includes a new Number.isNaNbut it looks like (imo) that this is also broken...

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

I would expect

我希望

Number.isNaN('RAWRRR')

To return true, since it's a string, and cannot be converted to a number... However...

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

enter image description here

在此处输入图片说明

It seems that things that I would consider... not a number, are indeed, not, not a number...

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

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

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

The examples on MDN say:

MDN 上的例子说:

Number.isNaN("blabla"); // e.g. this would have been true with isNaN

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

I don't understand how this is "More robust version of the original global isNaN." when I cannot check to see if things are not a number.

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

This would mean we're still subjected to doing actual type checking as well as checking isNaN... which seems silly...

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

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

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

The ES3 draft here basically says, everything is always false, except with its Number.NaN

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

Does anyone else find this is broken or am I just not understanding the point of isNaN?

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

回答by BoltClock

isNaN()and Number.isNaN()both test if a value is (or, in the case of isNaN(), can be converted to a number-type value that represents) the NaNvalue. In other words, "NaN" does not simply mean "this value is not a number", it specifically means "this value is a numericNot-a-Number value according to IEEE-754".

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

The reason all your tests above return false is because all of the given values can be converted to a numeric value that is not NaN:

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

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

The reason isNaN()is "broken" is because, ostensibly, type conversions aren't supposed to happen when testing values. That is the issue Number.isNaN()is designed to address. In particular, Number.isNaN()will onlyattempt to compare a value to NaNif the value is a number-type value. Any other type will return false, even if they are literally "not a number", because the typeof the value NaNis number. See the respective MDN docs for isNaN()and Number.isNaN().

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

If you simply want to determine whether or not a value is of the number type, even if that value is NaN, use typeofinstead:

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

typeof 'RAWRRR' === 'number' // false

回答by JLRishe

No, the original isNaNis broken. You are not understanding the point of isNaN.

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

The purpose of both of these functions is to determine whether or not something has the value NaN. This is provided because something === NaNwill always be falseand therefore can't be used to test this. (side note: something !== somethingis actually a reliable, although counter-intuitive, test for NaN)

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

The reason isNaNis broken is that it can return truein cases when a value is not actually NaN. This is because it first coerces the value to a number.

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

So

所以

isNaN("hello")

is true, even though "hello"is not NaN.

true,即使"hello"不是NaN

If you want to check whether a value actually is a finite number, you can use:

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

Number.isFinite(value)

If you want to test whether a value is a finite number or a string representation of one, you can use:

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

Number.isFinite(value) || (Number.isFinite(Number(value)) && typeof value === 'string')

回答by Tom Fenech

The key difference between the two is that the global isNaN(x)function performs a conversion of the parameter xto a number. So

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

isNaN("blabla") === true

because Number("blabla")results in NaN

因为Number("blabla")结果NaN

There are two definitions of "not a number" here and that's perhaps where the confusion lies. Number.isNaN(x)only returns true for the IEEE 754 floating point specification's definition of Not a Number, for example:

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

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

as opposed to determining whether the object being passed in is of numeric type or not. Some ways of doing that are:

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

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

回答by kaspermoerch

As mentioned in a comment isNaN()and Number.isNaN()both check that the value you pass in is not equal to the value NaN. The key here is that NaNis an actual value and not an evaluated result e.g. "blabla"is a Stringand the value is "blabla"which means it is not the value "NaN".

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

A plausible solution would be doing something like:

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

Number.isNaN(Number("blabla")); //returns true.

回答by Hyman Giffin

Basically, window.isNaNperforms a type conversion to a number, then checks if it is NaN. Whereas, Number.isNaNdoesn't try to convert its argument to a number. So basically, you can think of window.isNaN, and Number.isNaNas working like so.

基本上,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;
}

Please note that you don't need actually to use the window.to call isNaNor Number.isNaN. Rather, I am just using it to provide a better distinction between the two similarly-named methods to try to cut down on confusion.

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

~ Happy Coding!

~快乐编码!

回答by sendon1982

The following works because NaN is the only value in javascript which is not equal to itself.

以下有效,因为 NaN 是 javascript 中唯一不等于自身的值。

Number.isNaN = Number.isNaN || function(value) {     
    return value !== value;
}

回答by George

Per, MDN, it (NaN) is the returned value when Math functions failand as such it is a specific value. Perhaps a better name would have been, MathFunctionFailed.

Per, MDN, it (NaN) 是 Math 函数失败时的返回值,因此它是一个特定值。也许更好的名字是,MathFunctionFailed

To determine if something is a number requires parsing which fails nicely over a broad range of non numeric inputs, successfully detecting numbers and strings representing numbers, hence:

要确定某事物是否是数字,需要解析在广泛的非数字输入范围内失败,成功检测数字和表示数字的字符串,因此:

function isNumber(v) {return Number.isNaN(parseFloat(v)); }

function isNumber(v) {return Number.isNaN(parseFloat(v)); }

回答by aMarCruz

@phill, as stated in other responses, neither is broken.

@phill,如其他回复中所述,两者都没有损坏。

Number.isNaNwork on a number or instance of Number, so even Number.isNaN(new Date(NaN))is false.

Number.isNaN处理 的数量或实例Number,因此 evenNumber.isNaN(new Date(NaN))为假。

isNaN, on the other hand, is generic and tries to convert its parameter to a number before checking it.

isNaN,另一方面,是通用的,并在检查之前尝试将其参数转换为数字。

If you want to determine if a value is (or contains) NaN, you can use this function:

如果要确定值是否为 (或 contains) NaN,可以使用此函数:

function valueIsNaN(value) {
  // eslint-disable-next-line no-self-compare
  return value !== value || typeof value == 'object' && Number.isNaN(value.valueOf());
}

回答by Olexandr

I use a simple workaround to check Number.isNaN():

我使用一个简单的解决方法来检查 Number.isNaN():

    let value = 'test';
    Number.isNaN(-value); // true
    value = 42;
    Number.isNaN(-value); // false

js trying to convert the value to the negative Number, if the conversion is failed - we have NaN.

js 尝试将值转换为负数,如果转换失败 - 我们有 NaN。

Simple, isn't it?

很简单,不是吗?

Moreover, online benchmark tests say Number.isNaN is lighter than isNaN.

此外,在线基准测试表明 Number.isNaN 比 isNaN 更轻。

回答by acagastya

Number.isNaN(x)checks if x is directly evaluated to NaNor not.

Number.isNaN(x)检查 x 是否被直接评估为NaN

RAWRis not the same as NaN. Think of NaNas an entity to represent the result of some mathematical calculation where the computer does not know how to represent the number.

RAWR不一样NaN。将其NaN视为表示某些数学计算结果的实体,其中计算机不知道如何表示数字。

A mathematical operation is not going to yield a non-numeric result, hence the typeofNaNis number.

数学运算不会产生非数字结果,因此typeofNaNnumber

The string RAWRhad undergone no mathematical operation to yield NaN. However, if you were to call Number.isNaN(+'RAWR'), it would result in NaNsince the unary +operator is trying to convert 'RAWR'to a number.

字符串RAWR没有经过数学运算以产生NaN. 但是,如果您要调用Number.isNaN(+'RAWR'),则会导致NaN一元运算+符试图转换'RAWR'为数字。

On the other hand, isNaN(y)tells whether ycan be converted to a number or not. If isNaN(y)is false, ycan be converted to a number. But if isNaN(y)is true, ycan notbe converted to a number.

另一方面,isNaN(y)告诉是否y可以转换为数字。如果isNaN(y)falsey则可以转换为数字。但如果isNaN(y)为真,y无法转换为数字。

So a good rule of thumb is:

所以一个好的经验法则是:

  1. Do I want to check if xcan be successfully converted to a number? Use isNaN(x) == falsein that case. Unsuccessful conversion results in NaN.
  2. Do I want to check if xis evaluated to NaN? Use Number.isNaN(x) == truefor that.
  1. 我要检查是否x可以成功转换为数字?isNaN(x) == false在这种情况下使用。不成功的转换导致NaN.
  2. 我想检查是否x被评估为NaNNumber.isNaN(x) == true为此使用。