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,即使它们实际上是“不是数字”,因为值 NaN
的 type 是数字。请参阅 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.isNaN
和Number.isNaN
是这样工作的。
window.isNaN = function(n)
return Number(n) !== Number(n);
window.Number.isNaN = function(n)
return n !== n;
请注意,您实际上不需要使用window.
来调用isNaN
或Number.isNaN
。相反,我只是用它来更好地区分这两种名称相似的方法,以减少混淆。
~快乐编码!
【讨论】:
【参考方案6】:1. Number.isNaN
alert(Number.isNaN('Hello')); // false
它不应该返回true
因为Hello
是string
和它的Not A Number
对吗?但是让我们知道为什么它返回false
。
MDN docs 说:
如果给定值为 NaN 且其类型为 Number,则为 true;否则, 假的。
是 Hello
的值是 NaN
但类型是 string
,你可以检查类型如下:
alert(typeof `Hello`); // string
用法:
当您要检查值是否为NaN
且type
是否为数字时使用。
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
。
RAWR
与 NaN
不同。将NaN
视为一个实体,表示计算机不知道如何表示数字的某种数学计算的结果。
数学运算不会产生非数字结果,因此typeof
NaN
是number
。
字符串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() 更坏吗的主要内容,如果未能解决你的问题,请参考以下文章