Number.IsNaN() 比 isNaN() 更坏吗

Posted

技术标签:

【中文标题】Number.IsNaN() 比 isNaN() 更坏吗【英文标题】:Is Number.IsNaN() more broken than isNaN() 【发布时间】:2014-09-30 08:05:49 【问题描述】:

Soooooo isNaN 显然在 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 的意义?

【问题讨论】:

isNaN() 函数确定一个值是否为 NaN。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 它将为NaN 返回true 。字符串、布尔值、... 不是 NaN @dfsq 我不知道为什么 anyone 赞成您的评论,因为它完全错误。正如您在链接的 MDN 参考中所说,“isNaN 函数内部的强制具有有趣的规则”。例如,isNaN(a:1) 将返回 true。 ''not “不是数字”。它强制为 0,这是一个非常多的数字,而不是 NaN 我同意功能基本没用... 【参考方案1】:

isNaN()Number.isNaN() 都测试一个值是否是(或者,在isNaN() 的情况下,可以转换为表示)NaN 值的数字类型值。换句话说,“NaN”不仅仅意味着“这个值不是一个数字”,它具体意味着“这个值是一个 numeric 根据 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,即使它们实际上是“不是数字”,因为值 NaNtype 是数字。请参阅 isNaN()Number.isNaN() 的相应 MDN 文档。

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

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

【讨论】:

迄今为止我见过的最简洁的解释。 我会推荐:typeof value === 'number' && !isNaN(value)。因为typeof NaN === 'number'. 令人沮丧的是,他们引入了另一种检查 NaN 的方法,该方法以许多相同的方式(以及一些新的启动方式)被破坏。 @d512 显然你不明白这个答案,因为整点是isNaN 不是“破碎”。它不是检查该值是否为数字(您可以使用parseInt 或jQuery 的$.isNumeric 来执行此操作)-isNaN 实际上是检查该值是否为NaN,这是一个非常具体的特殊值JavaScript 中的含义。 @d512:仅仅因为您个人没有用于检查值是否为 NaN 的用例,并不会使其成为错误的算法或损坏。也许你可以提议增加一个 Number.isNumeric() 函数,但如果没有人这样做,我会感到惊讶。【参考方案2】:

不,原来的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')

【讨论】:

不完全是:Number.isFinite(parseFloat('1f')) 返回true @GabrielFlorit 你是对的。我想我现在已经修好了。 很好的解释【参考方案3】:

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

一个可行的解决方案是:

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

【讨论】:

你的解决方案在Number.isNaN(Number(" "))这样的情况下仍然不起作用。 @JLRishe 其他可能性:const someValue = <anything>; !isNaN(+someValue)const someValue = <anything>; !isNaN(parseFloat(someValue))【参考方案4】:

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

【讨论】:

【参考方案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;

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

~快乐编码!

【讨论】:

【参考方案6】:

1. Number.isNaN

alert(Number.isNaN('Hello')); // false 

它不应该返回true 因为Hellostring 和它的Not A Number 对吗?但是让我们知道为什么它返回false

MDN docs 说:

如果给定值为 NaN 且其类型为 Number,则为 true;否则, 假的。

Hello 的值是 NaN 但类型是 string ,你可以检查类型如下:

alert(typeof `Hello`);  // string

用法:

当您要检查值是否为NaNtype 是否为数字时使用。

2。 isNaN

alert(isNaN('Hello')); // true

MDN docs 说:

如果给定值为 NaN,则为真;否则为假。

用法:

当你想检查值是否只是 NaN 时使用。

3. jQuery.isNumeric()

Jquery Docs 说:

确定其参数是否代表 JavaScript 数字。

alert($.isNumeric('Hello')); // false
alert($.isNumeric(3)); //true

用法:

当您要检查值是数字或可以转换为数字时使用。

Reference

【讨论】:

【参考方案7】:

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

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

【讨论】:

【参考方案8】:

Per,MDN,it (NaN) is the returned value when Math functions fail,因此它是一个特定的值。也许更好的名字是MathFunctionFailed

要确定某物是否为数字,需要解析,该解析在广泛的非数字输入中很好地失败,成功检测数字和表示数字的字符串,因此:

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

【讨论】:

MathFunctionFailed 这样的东西会方式太冗长而无法包含在 1985 年的浮点数标准化中。NaN 及其语义行为,包括 @ 987654326@ 行为,甚至早于导致 IEEE-754 的标准化过程,而 IEEE-754 又远早于 JavaScript(甚至是 WWW)。 感谢您的历史课。 :)【参考方案9】:

@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());

【讨论】:

【参考方案10】:

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

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

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

很简单,不是吗?

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

【讨论】:

【参考方案11】:

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

RAWRNaN 不同。将NaN 视为一个实体,表示计算机不知道如何表示数字的某种数学计算的结果。

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

字符串RAWR 没有经过数学运算得到NaN。但是,如果您要调用 Number.isNaN(+'RAWR'),它将导致 NaN,因为一元 + 运算符正在尝试将 'RAWR' 转换为数字。

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

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

    是否要检查x是否可以成功转换为数字?在这种情况下使用isNaN(x) == false。转换不成功会导致NaN。 我是否要检查 x 是否被评估为 NaN?为此请使用 Number.isNaN(x) == true

【讨论】:

以上是关于Number.IsNaN() 比 isNaN() 更坏吗的主要内容,如果未能解决你的问题,请参考以下文章

js中isNaN和Number.isNaN的区别

JS中isNaN()函数的一点认识

Js判断值是否是NaN

NaN

JavaScript - 数值类型的判断与常用转换方式

ES6为数值扩展