Is Number.IsNaN()比 isNaN()破碎得更多

很明显,Soooooo isNaN在 JavaScript 中出现了以下问题:

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

返回错误,当他们似乎都是... 不是一个数字..。

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

我希望

Number.isNaN('RAWRRR')

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

enter image description here

看起来我认为的东西... 不是一个数字,事实上,不是,不是一个数字..。

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

MDN 上的例子说:

Number.isNaN (“ blabla”) ;//例如,对于 isNaN,这是正确的

我不明白这怎么会是“原来的 global isNaN 的更健壮的版本”当我不能检查,看看事情是不是一个数字。

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

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

这里的 ES3草案基本上说,除了 Number.NaN 之外,所有东西都是假的

还有人发现这个坏了吗? 还是我不明白 isNaN 的意思?

26602 次浏览

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

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

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

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

如果您只是想确定一个值是否为数字类型 即使这个值是 NaN,那么可以使用 typeof:

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

不,原来的 isNaN坏了,你不明白 isNaN的意思。

这两个函数的作用都是确定某个值是否为 NaN。这是因为 something === NaN将始终是 false,因此不能用来测试这一点。 (附注: something !== something实际上是一个可靠的,尽管违反直觉,对 NaN的测试)

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

那么

isNaN("hello")

true,即使 "hello"不是 NaN

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

Number.isFinite(value)

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

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

正如注释 isNaN()Number.isNaN()中提到的,它们都检查传入的值是否不等于值 NaN。这里的关键是,NaN是一个实际值,而不是一个评估结果,例如,"blabla"是一个 String,值是 "blabla",这意味着它不是值 "NaN"

一个合理的解决方案是这样做:

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

两者之间的关键区别在于,全局 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]"

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

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

快乐编码!

下面的代码可以工作,因为 NaN 是 javascript 中唯一不等于它本身的值。

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

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

为了确定某个东西是否是一个数字,需要对大量非数字输入进行很好的解析,成功地检测到代表数字的数字和字符串,因此:

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

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

Number.isNaN作用于 Number的一个数字或实例,所以即使 Number.isNaN(new Date(NaN))也是假的。

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

如果要确定某个值是否为(或包含) NaN,可以使用以下函数:

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

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

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

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

很简单,不是吗?

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

Number.isNaN(x)检查 x 是否直接计算为 NaN

RAWR不同于 NaN。把 NaN想象成一个实体,用来表示计算机不知道如何表示数字的某些数学计算的结果。

数学运算不会产生非数值结果,因此 typeof NaNnumber

字符串 RAWR没有经过数学运算产生 NaN。但是,如果您要调用 Number.isNaN(+'RAWR'),它将导致 NaN,因为一元 +操作员正试图将 'RAWR'转换为一个数字。

另一方面,isNaN(y)告诉 y是否可以转换成一个数字。如果 isNaN(y)falsey可以转换成一个数字。但是如果 isNaN(y)为真,y就可以将 没有转换成一个数字。

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

  1. 我想检查是否 x可以成功地转换为一个数字?在这种情况下使用 isNaN(x) == false。转换失败导致 NaN
  2. 我想检查 x是否被评估为 NaN? 使用 Number.isNaN(x) == true