use-isnan
Require calls to isNaN()
when checking for NaN
Using the recommended
config from @eslint/js
in a configuration file enables this rule
Some problems reported by this rule are manually fixable by editor suggestions
In JavaScript, NaN
is a special value of the Number
type. It’s used to represent any of the “not-a-number” values represented by the double-precision 64-bit format as specified by the IEEE Standard for Binary Floating-Point Arithmetic.
Because NaN
is unique in JavaScript by not being equal to anything, including itself, the results of comparisons to NaN
are confusing:
NaN === NaN
orNaN == NaN
evaluate tofalse
NaN !== NaN
orNaN != NaN
evaluate totrue
Therefore, use Number.isNaN()
or global isNaN()
functions to test whether a value is NaN
.
Rule Details
This rule disallows comparisons to NaN
.
Examples of incorrect code for this rule:
/*eslint use-isnan: "error"*/ if () { // ... } if () { // ... } if () { // ... } if () { // ... }
Examples of correct code for this rule:
/*eslint use-isnan: "error"*/ if (isNaN(foo)) { // ... } if (!isNaN(foo)) { // ... }
Options
This rule has an object option, with two options:
"enforceForSwitchCase": true
(default) additionally disallowscase NaN
andswitch(NaN)
inswitch
statements."enforceForIndexOf": true
additionally disallows the use ofindexOf
andlastIndexOf
methods withNaN
. Default isfalse
, meaning that this rule by default does not warn aboutindexOf(NaN)
orlastIndexOf(NaN)
method calls.
enforceForSwitchCase
The switch
statement internally uses the ===
comparison to match the expression’s value to a case clause. Therefore, it can never match case NaN
. Also, switch(NaN)
can never match a case clause.
Examples of incorrect code for this rule with "enforceForSwitchCase"
option set to true
(default):
/*eslint use-isnan: ["error", {"enforceForSwitchCase": true}]*/ switch (foo) { case 1: baz(); break; // ... } switch (foo) { case 1: baz(); break; // ... }
Examples of correct code for this rule with "enforceForSwitchCase"
option set to true
(default):
/*eslint use-isnan: ["error", {"enforceForSwitchCase": true}]*/ if (Number.isNaN(foo)) { bar(); } else { switch (foo) { case 1: baz(); break; // ... } } if (Number.isNaN(a)) { bar(); } else if (Number.isNaN(b)) { baz(); } // ...
Examples of correct code for this rule with "enforceForSwitchCase"
option set to false
:
/*eslint use-isnan: ["error", {"enforceForSwitchCase": false}]*/ switch (foo) { case NaN: bar(); break; case 1: baz(); break; // ... } switch (NaN) { case a: bar(); break; case b: baz(); break; // ... } switch (foo) { case Number.NaN: bar(); break; case 1: baz(); break; // ... } switch (Number.NaN) { case a: bar(); break; case b: baz(); break; // ... }
enforceForIndexOf
The following methods internally use the ===
comparison to match the given value with an array element:
Therefore, for any array foo
, foo.indexOf(NaN)
and foo.lastIndexOf(NaN)
will always return -1
.
Set "enforceForIndexOf"
to true
if you want this rule to report indexOf(NaN)
and lastIndexOf(NaN)
method calls.
Examples of incorrect code for this rule with "enforceForIndexOf"
option set to true
:
/*eslint use-isnan: ["error", {"enforceForIndexOf": true}]*/ const hasNaN = >= 0; const firstIndex = ; const lastIndex = ; const indexWithSequenceExpression = ; const firstIndexFromSecondElement = ; const lastIndexFromSecondElement = ;
Examples of correct code for this rule with "enforceForIndexOf"
option set to true
:
/*eslint use-isnan: ["error", {"enforceForIndexOf": true}]*/ function myIsNaN(val) { return typeof val === "number" && isNaN(val); } function indexOfNaN(arr) { for (let i = 0; i < arr.length; i++) { if (myIsNaN(arr[i])) { return i; } } return -1; } function lastIndexOfNaN(arr) { for (let i = arr.length - 1; i >= 0; i--) { if (myIsNaN(arr[i])) { return i; } } return -1; } const hasNaN = myArray.some(myIsNaN); const hasNaN1 = indexOfNaN(myArray) >= 0; const firstIndex = indexOfNaN(myArray); const lastIndex = lastIndexOfNaN(myArray); // ES2015 const hasNaN2 = myArray.some(Number.isNaN); // ES2015 const firstIndex1 = myArray.findIndex(Number.isNaN); // ES2016 const hasNaN3 = myArray.includes(NaN);
Known Limitations
This option checks methods with the given names, even if the object which has the method is not an array.
Version
This rule was introduced in ESLint v0.0.6.