SonarQube 建议 an!==a 而不是 a===MaN

SonarQube suggest a!==a instead of a===NaN

有一个 SonarQube JavaScript 规则 (javascript:S2688) 说 a === NaN 的使用是一个错误,因为它总是 false.

我同意这一点,但我认为使用 a !== a 代替(SonarQube 建议)是一个非常糟糕的主意。 这是一个有趣的 JavaScript 事实,但肯定不是 "best practice".

Number.isNaN(a)呢?为什么这不是建议的解决方案?是否有任何我遗漏的差异或问题?

the use of a === NaN is a bug because it's always false.

行为 不是错误,因为它是 NaN 定义的工作方式。但是,如果您实际上在程序中使用了 a === NaN,那么 that 将是一个错误,因为总是 false 结果。

a !== a instead ... is a very bad idea. It's a funny JavaScript fact but certainly not a "best practice".

我不同意你的观点"certainly"。由于原始全局 isNaN() 函数存在问题(我稍后会解释),a !== a 一直是测试 NaN 的最佳方法。所以实际上使用该技术是一种非常普遍的做法,我希望绝大多数有经验的 JavaScript 开发人员都熟悉它。

NaN 唯一测试为不等于自身的值。

What about isNaN(a)? Why is this not the suggested solution? Are there any differences or problems which I've missed?

原始的全局 isNaN() function 实际上并不测试其参数是否为 NaN 也不测试其参数是否为其他非-数值。它所做的是首先尝试将其参数转换为数字,然后测试该转换的结果是否等于 NaN。这种隐式转换意味着,例如 isNaN("test") returns true 即使字符串不等于值 NaN。而 isNaN("") returns false 因为可以将空字符串强制转换为 0。如果您正在寻找这种行为,那么是的,请使用 isNaN().

所以所有这些就是为什么 ECMAScript 6/2015 引入了一个新函数,Number.isNaN(),它确实 专门 测试值 NaN,给出与老式 a !== a.

等效的结果

如评论中所建议,对于不支持 Number.isNaN() 的旧版浏览器(基本上是旧版 IE),如果您想要比 a !== a 更清晰的内容并且不介意更长的代码,您可以这样做:

typeof a == "number" && isNaN(a)

...这是两个 Number.isNaN() polyfills suggested by MDN 之一。 (另一个只是使用a !== a。)