mirror of
https://git.proxmox.com/git/pve-eslint
synced 2025-10-05 20:24:05 +00:00

includes a (minimal) working wrapper Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
202 lines
4.7 KiB
Markdown
202 lines
4.7 KiB
Markdown
# require calls to `isNaN()` when checking for `NaN` (use-isnan)
|
|
|
|
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` or `NaN == NaN` evaluate to false
|
|
* `NaN !== NaN` or `NaN != NaN` evaluate to true
|
|
|
|
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:
|
|
|
|
```js
|
|
/*eslint use-isnan: "error"*/
|
|
|
|
if (foo == NaN) {
|
|
// ...
|
|
}
|
|
|
|
if (foo != NaN) {
|
|
// ...
|
|
}
|
|
```
|
|
|
|
Examples of **correct** code for this rule:
|
|
|
|
```js
|
|
/*eslint use-isnan: "error"*/
|
|
|
|
if (isNaN(foo)) {
|
|
// ...
|
|
}
|
|
|
|
if (!isNaN(foo)) {
|
|
// ...
|
|
}
|
|
```
|
|
|
|
## Options
|
|
|
|
This rule has an object option, with two options:
|
|
|
|
* `"enforceForSwitchCase": true` (default) additionally disallows `case NaN` and `switch(NaN)` in `switch` statements.
|
|
* `"enforceForIndexOf": true` additionally disallows the use of `indexOf` and `lastIndexOf` methods with `NaN`. Default is `false`, meaning that this rule by default does not warn about `indexOf(NaN)` or `lastIndexOf(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):
|
|
|
|
```js
|
|
/*eslint use-isnan: ["error", {"enforceForSwitchCase": true}]*/
|
|
|
|
switch (foo) {
|
|
case NaN:
|
|
bar();
|
|
break;
|
|
case 1:
|
|
baz();
|
|
break;
|
|
// ...
|
|
}
|
|
|
|
switch (NaN) {
|
|
case a:
|
|
bar();
|
|
break;
|
|
case b:
|
|
baz();
|
|
break;
|
|
// ...
|
|
}
|
|
```
|
|
|
|
Examples of **correct** code for this rule with `"enforceForSwitchCase"` option set to `true` (default):
|
|
|
|
```js
|
|
/*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`:
|
|
|
|
```js
|
|
/*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;
|
|
// ...
|
|
}
|
|
```
|
|
|
|
### enforceForIndexOf
|
|
|
|
The following methods internally use the `===` comparison to match the given value with an array element:
|
|
|
|
* [`Array.prototype.indexOf`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.indexof)
|
|
* [`Array.prototype.lastIndexOf`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.lastindexof)
|
|
|
|
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`:
|
|
|
|
```js
|
|
/*eslint use-isnan: ["error", {"enforceForIndexOf": true}]*/
|
|
|
|
var hasNaN = myArray.indexOf(NaN) >= 0;
|
|
|
|
var firstIndex = myArray.indexOf(NaN);
|
|
|
|
var lastIndex = myArray.lastIndexOf(NaN);
|
|
```
|
|
|
|
Examples of **correct** code for this rule with `"enforceForIndexOf"` option set to `true`:
|
|
|
|
```js
|
|
/*eslint use-isnan: ["error", {"enforceForIndexOf": true}]*/
|
|
|
|
function myIsNaN(val) {
|
|
return typeof val === "number" && isNaN(val);
|
|
}
|
|
|
|
function indexOfNaN(arr) {
|
|
for (var i = 0; i < arr.length; i++) {
|
|
if (myIsNaN(arr[i])) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
function lastIndexOfNaN(arr) {
|
|
for (var i = arr.length - 1; i >= 0; i--) {
|
|
if (myIsNaN(arr[i])) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
var hasNaN = myArray.some(myIsNaN);
|
|
|
|
var hasNaN = indexOfNaN(myArray) >= 0;
|
|
|
|
var firstIndex = indexOfNaN(myArray);
|
|
|
|
var lastIndex = lastIndexOfNaN(myArray);
|
|
|
|
// ES2015
|
|
var hasNaN = myArray.some(Number.isNaN);
|
|
|
|
// ES2015
|
|
var firstIndex = myArray.findIndex(Number.isNaN);
|
|
|
|
// ES2016
|
|
var hasNaN = 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.
|