58 lines
2.9 KiB
Plaintext
58 lines
2.9 KiB
Plaintext
== Why is this an issue?
|
|
|
|
Comparing the value to itself may be either a refactoring error or an outdated way of checking if the value is of a numeric data type but not a valid number. This special numeric value is represented by `NaN` global property, where `NaN` stands for "Not-a-Number". `NaN` is returned as a result when an arithmetic operation or mathematical function is performed, and the result is undefined or unrepresentable as a valid number.
|
|
|
|
Detecting whether a value is `NaN` in JavaScript was previously problematic because of the way `NaN` behaves in comparison operations. `NaN` is not equal to any value, including itself, so comparing the value to `NaN` will always return false. In other words, if a value is not equal to itself, it can only be `NaN`.
|
|
|
|
This method of detecting `NaN` can be confusing and should be avoided. ES6 introduced a special function `Number.isNaN()` which only returns `true` if the argument is `NaN` value. For clarity and consistency this function should be used to detect `NaN` instead of all other methods.
|
|
|
|
[source,javascript,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
if (value !== value){ // Noncompliant: use Number.isNaN()
|
|
processNaN(value);
|
|
}
|
|
----
|
|
|
|
To fix your code replace self-comparison with `Number.isNaN()` function.
|
|
|
|
[source,javascript,diff-id=1,diff-type=compliant]
|
|
----
|
|
if (Number.isNaN(value)){
|
|
processNaN(value);
|
|
}
|
|
----
|
|
|
|
Do not confuse `Number.isNaN()` with the legacy global `isNaN()` function. While they serve a similar purpose, the behavior is very different - the global `isNaN()` tries to convert its argument into a number before checking if it is `NaN`. If the argument cannot be converted into a number, `isNaN()` will return true, which may not be the desired behavior in all cases.
|
|
|
|
[source,javascript]
|
|
----
|
|
isNaN('some text'); // true: Number('some text') returns NaN
|
|
Number.isNaN('some text'); // false: 'some text' is not NaN
|
|
----
|
|
|
|
You should use the `Number.isNaN()` method over `isNaN()` to perform a strict check for `NaN` without any type conversion.
|
|
|
|
If the intention was not to detect whether a value was NaN, fix the issue by not comparing the variable against itself.
|
|
|
|
[source,javascript,diff-id=1,diff-type=compliant]
|
|
----
|
|
if (value !== anotherValue){
|
|
// ...
|
|
}
|
|
----
|
|
|
|
|
|
== Resources
|
|
|
|
=== Documentation
|
|
|
|
* MDN web docs - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN[``++NaN++``]
|
|
* MDN web docs - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN[``++Number.isNaN()++``]
|
|
* MDN web docs - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN[``++isNaN()++``]
|
|
* MDN web docs - https://developer.mozilla.org/en-US/docs/Glossary/Type_Conversion[Type conversion]
|
|
|
|
=== Related rules
|
|
|
|
* S1764 - Identical expressions should not be used on both sides of a binary operator
|
|
* S2688 - "NaN" should not be used in comparisons
|