Skip to content

Commit 5ca65c4

Browse files
pvskarthikeyasindresorhus
authored andcommitted
Add no-array-instanceof rule (fixes #11) (#58)
1 parent 9c8325f commit 5ca65c4

File tree

5 files changed

+102
-1
lines changed

5 files changed

+102
-1
lines changed

docs/rules/no-array-instanceof.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Require `Array.isArray()` check instead of `instanceof Array`
2+
3+
While the `instanceof Array` works, it is unreliable across environments Eg: multi-frame DOM environments (iframes). Hence, `Array.isArray()` is recommended.
4+
5+
## Fail
6+
7+
```js
8+
array instanceof Array;
9+
[1,2,3] instanceof Array;
10+
```
11+
12+
## Pass
13+
14+
```js
15+
Array.isArray(array);
16+
Array.isArray([1,2,3]);
17+
```

index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ module.exports = {
1919
'unicorn/no-abusive-eslint-disable': 'error',
2020
'unicorn/no-process-exit': 'error',
2121
'unicorn/throw-new-error': 'error',
22+
'unicorn/no-array-instanceof': 'error',
2223
'unicorn/number-literal-case': 'error'
2324
}
2425
}

readme.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ Configure it in `package.json`.
3939
"unicorn/no-abusive-eslint-disable": "error",
4040
"unicorn/no-process-exit": "error",
4141
"unicorn/throw-new-error": "error",
42-
"unicorn/number-literal-case": "error"
42+
"unicorn/number-literal-case": "error",
43+
"unicorn/no-array-instanceof": "error"
4344
}
4445
}
4546
}
@@ -55,6 +56,7 @@ Configure it in `package.json`.
5556
- [no-process-exit](docs/rules/no-process-exit.md) - Disallow `process.exit()`.
5657
- [throw-new-error](docs/rules/throw-new-error.md) - Require `new` when throwing an error. *(fixable)*
5758
- [number-literal-case](docs/rules/number-literal-case.md) - Enforce lowercase identifier and uppercase value for number literals. *(fixable)*
59+
- [no-array-instanceof](docs/rules/no-array-instanceof.md) - Disallow `instanceof Array`, instead use `Array.isArray()`. *(fixable)*
5860

5961

6062
## Recommended config

rules/no-array-instanceof.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
'use strict';
2+
3+
const create = context => ({
4+
BinaryExpression: node => {
5+
if (node.operator === 'instanceof' && node.right.type === 'Identifier' && node.right.name === 'Array') {
6+
// Get the source code and extract the left part.
7+
const arraySourceCode = context.getSourceCode().text.slice(node.left.range[0], node.left.range[1]);
8+
context.report({
9+
node,
10+
message: 'Use `Array.isArray()` instead of `instanceof Array`',
11+
fix: fixer => fixer.replaceText(node, `Array.isArray(${arraySourceCode})`)
12+
});
13+
}
14+
}
15+
});
16+
17+
module.exports = {
18+
create,
19+
meta: {
20+
fixable: 'code'
21+
}
22+
};

test/no-array-instanceof.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import test from 'ava';
2+
import avaRuleTester from 'eslint-ava-rule-tester';
3+
import rule from '../rules/no-array-instanceof';
4+
5+
const ruleTester = avaRuleTester(test, {
6+
env: {
7+
es6: true
8+
}
9+
});
10+
11+
const errors = [{
12+
ruleId: 'no-array-instanceof',
13+
message: 'Use `Array.isArray()` instead of `instanceof Array`'
14+
}];
15+
16+
ruleTester.run('avoid-array-instanceof', rule, {
17+
valid: [
18+
'Array.isArray(arr)',
19+
'arr instanceof Object',
20+
'arr instanceof array',
21+
'a instanceof \'array\'',
22+
'a instanceof ArrayA',
23+
'a.x[2] instanceof foo()',
24+
'Array.isArray([1,2,3]) === true',
25+
'"arr instanceof Array"'
26+
],
27+
invalid: [
28+
{
29+
code: 'arr instanceof Array',
30+
output: 'Array.isArray(arr)',
31+
errors
32+
},
33+
{
34+
code: '[] instanceof Array',
35+
output: 'Array.isArray([])',
36+
errors
37+
},
38+
{
39+
code: '[1,2,3] instanceof Array === true',
40+
output: 'Array.isArray([1,2,3]) === true',
41+
errors
42+
},
43+
{
44+
code: 'fun.call(1, 2, 3) instanceof Array',
45+
output: 'Array.isArray(fun.call(1, 2, 3))',
46+
errors
47+
},
48+
{
49+
code: 'obj.arr instanceof Array',
50+
output: 'Array.isArray(obj.arr)',
51+
errors
52+
},
53+
{
54+
code: 'foo.bar[2] instanceof Array',
55+
output: 'Array.isArray(foo.bar[2])',
56+
errors
57+
}
58+
]
59+
});

0 commit comments

Comments
 (0)