biome style/useArrayLiterals
labelled safe
Analysis Nemotron 3 Super
The rule flags uses of the Array constructor without exactly one numeric argument, recommending replacement with array literals.
Fix: Replace Array(...) calls with [...] containing the same arguments, preserving spread elements and argument order; replace new Array(...) similarly while dropping the 'new' keyword.
11 hazards
- Rewriting Array(x) where x is non-numeric changes behavior: Array(undefined) becomes [undefined] instead of [], altering length and element values.
- If Array is shadowed by a local variable, replacing Array(...) with [...] breaks the reference to the local binding, potentially changing the constructor used.
- When Array(...) appears in a larger expression (e.g., return Array(...)), moving comments attached to the parentheses or arguments may alter comment placement relative to surrounding tokens.
- In contexts like typeof Array(...) === 'function', replacing with [...] changes the result from 'object' to 'object' but may affect type checks relying on constructor identity in non-standard environments.
- If the Array constructor call has trailing comments (e.g., Array(1, 2 /* comment */)), the autofix may drop or misplace those comments during rewrite.
- Using Array(...) in a comma sequence (e.g., let x = Array(1), y;) risks breaking parsing if the fix removes necessary delimiters or alters precedence unexpectedly.
- When Array(...) is used as a function argument (e.g., fn(Array(1, 2))), the fix preserves semantics only if Array is the global constructor; if redefined locally, the literal [] behaves differently.
- In eval() or Function() constructor contexts, the rewritten literal may be parsed differently due to strict mode implications or reserved word handling.
- If the argument to Array(...) is an expression with side effects (e.g., Array(f())), the fix evaluates f() once as before, but if the literal is placed in a different syntactic position, evaluation order relative to other expressions could shift.
- For Array(...) with more than 2^32-1 arguments, the literal may fail silently or throw where the constructor would have succeeded, though both are practically infeasible.
- In rare cases involving __proto__ manipulation, replacing Array(...) with [] may alter inheritance if the literal is assigned to a prototype property expecting Array instance traits.
Programs
| id | result | title | hazard |
|---|---|---|---|
| r1-p001 | fix ok | Label/break/continue/finally interaction | label/break/continue control flow, finally blocks, early returns in nested blocks |
| r1-p002 | fix ok | Trailing comments preservation | If the Array constructor call has trailing comments (e.g., Array(1, 2 /* comment */)), the autofix may drop or misplace those comments during rewrite. |
| r1-p003 | silent prediction off | Local Array shadowing | When Array(...) is used as a function argument (e.g., fn(Array(1, 2))), the fix preserves semantics only if Array is the global constructor; if redefined locally, the literal [] behaves differently. |
| r1-p004 | fix ok | Var hoisting and redeclaration | var hoisting and re-declaration inside loops or after use |
| r1-p005 | fix ok | __proto__ and prototype interaction | __proto__ keys, prototype access, Object.assign vs spread |
| r1-p006 | fix ok | Comment attachment to removed/moved code | comments attached to the removed or moved code |
| r1-p007 | fix ok | Side effects in argument evaluation order | If the argument to Array(...) is an expression with side effects (e.g., Array(f())), the fix evaluates f() once as before, but if the literal is placed in a different syntactic position, evaluation or |
| r1-p008 | fix ok | Arguments object and parameters interaction | arguments object, function.length, default parameters, rest parameters |
| r2-p001 | fix ok | Order of evaluation duplication - side effect executed twice | order of evaluation when expressions are merged, duplicated or deleted (side effects run twice or never) |
| r2-p002 | fix ok | __proto__ key assignment via computed property using array constructor | __proto__ keys, prototype access, Object.assign vs spread |
| r2-p003 | silent prediction off | Numeric/string coercion with custom valueOf affecting resulting array contents | numeric/string coercion: + vs template literal, objects with toString/valueOf, Symbol, BigInt |
| r2-p004 | fix ok | Static block initialization using array constructor influencing class field | class fields, static blocks, private names, super calls |
| r2-p005 | silent prediction off | Eval context altering parsing of rewritten array literal due to strict mode | In eval() or Function() constructor contexts, the rewritten literal may be parsed differently due to strict mode implications or reserved word handling. |
| r2-p006 | fix ok | Function declaration inside switch case capturing array constructor via closure | function declarations inside blocks, switch cases, labeled statements |
| r2-p007 | silent prediction off | __proto__ assignment replacing Array instance with literal altering prototype chain expectations | In rare cases involving __proto__ manipulation, replacing Array(...) with [] may alter inheritance if the literal is assigned to a prototype property expecting Array instance traits. |
| r2-p008 | fix ok | Name collision after hoisting due to var redeclaration in loop interacting with array constructor | name collisions across scopes after a move (shadowing) |
Sources
r1-p001 · Label/break/continue/finally interaction
1outer:
2for (let i = 0; i < 2; i++) {
3 try {
4 const arr = Array(i, i + 1);
5 if (arr[0] === 0) break outer;
6 console.log('loop', arr);
7 } finally {
8 console.log('finally', i);
9 }
10}
11console.log('done');
--- orig.js 2026-10-17 16:59:09.951816001 -0400 +++ fixed.js 2026-10-17 16:59:10.234819674 -0400 @@ -1,7 +1,7 @@ outer: for (let i = 0; i < 2; i++) { try { - const arr = Array(i, i + 1); + const arr = [i, i + 1]; if (arr[0] === 0) break outer; console.log('loop', arr); } finally {
finally 0 done
r1-p002 · Trailing comments preservation
1function fn(x) { return x; }
2const result = fn(Array(1, 2 /* keep this */));
3console.log(result);
--- orig.js 2026-10-17 16:59:10.405821893 -0400 +++ fixed.js 2026-10-17 16:59:10.681825474 -0400 @@ -1,3 +1,3 @@ function fn(x) { return x; } -const result = fn(Array(1, 2 /* keep this */)); +const result = fn([1, 2 /* keep this */]); console.log(result);
[ 1, 2 ]
r1-p003 · Local Array shadowing
1function test() {
2 const Array = () => ({ length: 0, push: () => {} });
3 const x = [];
4 x.push(Array(1, 2));
5 console.log(x[0].length);
6}
7test();
0
r1-p004 · Var hoisting and redeclaration
1for (var i = 0; i < 2; i++) {
2 var arr = Array(i, i + 1);
3 console.log(arr);
4}
5console.log('redeclare:', typeof arr);
6var arr = [99];
7console.log('after:', arr);
--- orig.js 2026-10-17 16:59:11.080830651 -0400 +++ fixed.js 2026-10-17 16:59:11.346834101 -0400 @@ -1,5 +1,5 @@ for (var i = 0; i < 2; i++) { - var arr = Array(i, i + 1); + var arr = [i, i + 1]; console.log(arr); } console.log('redeclare:', typeof arr);
[ 0, 1 ] [ 1, 2 ] redeclare: object after: [ 99 ]
r1-p005 · __proto__ and prototype interaction
1const obj = {};
2obj.__proto__ = Array(0, 1);
3console.log(obj.length);
4const copy = { ...obj };
5console.log(copy.length);
--- orig.js 2026-10-17 16:59:11.507836189 -0400 +++ fixed.js 2026-10-17 16:59:11.782839756 -0400 @@ -1,5 +1,5 @@ const obj = {}; -obj.__proto__ = Array(0, 1); +obj.__proto__ = [0, 1]; console.log(obj.length); const copy = { ...obj }; console.log(copy.length);
2 undefined
r1-p006 · Comment attachment to removed/moved code
1// start
2const x = Array(/* hello */1, /* world */2);
3// end
4console.log(x);
--- orig.js 2026-10-17 16:59:11.952841961 -0400 +++ fixed.js 2026-10-17 16:59:12.228845539 -0400 @@ -1,4 +1,4 @@ // start -const x = Array(/* hello */1, /* world */2); +const x = [/* hello */1, /* world */2]; // end console.log(x);
[ 1, 2 ]
r1-p007 · Side effects in argument evaluation order
1let log = '';
2function f() { log += 'f'; return 1; }
3function g() { log += 'g'; return 2; }
4const arr = Array(f(), g());
5console.log(log, arr);
--- orig.js 2026-10-17 16:59:12.401847782 -0400 +++ fixed.js 2026-10-17 16:59:12.664851191 -0400 @@ -1,5 +1,5 @@ let log = ''; function f() { log += 'f'; return 1; } function g() { log += 'g'; return 2; } -const arr = Array(f(), g()); +const arr = [f(), g()]; console.log(log, arr);
fg [ 1, 2 ]
r1-p008 · Arguments object and parameters interaction
1function test(a, b = Array(1, 2)) {
2 console.log('args:', arguments.length, arguments[1]);
3 console.log('b:', b);
4}
5test(0);
--- orig.js 2026-10-17 16:59:12.835853407 -0400 +++ fixed.js 2026-10-17 16:59:13.105856906 -0400 @@ -1,4 +1,4 @@ -function test(a, b = Array(1, 2)) { +function test(a, b = [1, 2]) { console.log('args:', arguments.length, arguments[1]); console.log('b:', b); }
args: 1 undefined b: [ 1, 2 ]
r2-p001 · Order of evaluation duplication - side effect executed twice
1let i = 0;
2function next() { return i++; }
3const arr = Array(next(), next());
4console.log(arr);
--- orig.js 2026-10-17 16:59:18.552927389 -0400 +++ fixed.js 2026-10-17 16:59:18.825930916 -0400 @@ -1,4 +1,4 @@ let i = 0; function next() { return i++; } -const arr = Array(next(), next()); +const arr = [next(), next()]; console.log(arr);
[ 0, 1 ]
r2-p002 · __proto__ key assignment via computed property using array constructor
1const obj = {};
2obj[`__proto__`] = Array(1, 2);
3console.log(obj.__proto__.length === 2 && obj.__proto__[0] === 1);
--- orig.js 2026-10-17 16:59:18.989933035 -0400 +++ fixed.js 2026-10-17 16:59:19.272936690 -0400 @@ -1,3 +1,3 @@ const obj = {}; -obj[`__proto__`] = Array(1, 2); +obj[`__proto__`] = [1, 2]; console.log(obj.__proto__.length === 2 && obj.__proto__[0] === 1);
true
r2-p003 · Numeric/string coercion with custom valueOf affecting resulting array contents
1const x = { valueOf: () => 42 };
2const arr = Array(x);
3console.log(arr.length === 1 && arr[0] === 42);
false
r2-p004 · Static block initialization using array constructor influencing class field
1class C {
2 static arr;
3 static { C.arr = Array(1, 2); }
4}
5console.log(C.arr.length === 2 && C.arr[0] === 1);
--- orig.js 2026-10-17 16:59:19.665941766 -0400 +++ fixed.js 2026-10-17 16:59:19.944945369 -0400 @@ -1,5 +1,5 @@ class C { static arr; - static { C.arr = Array(1, 2); } + static { C.arr = [1, 2]; } } console.log(C.arr.length === 2 && C.arr[0] === 1);
true
r2-p005 · Eval context altering parsing of rewritten array literal due to strict mode
1"use strict";
2let result;
3try {
4 result = eval("Array(1, 2)");
5} catch (e) {
6 result = e;
7}
8console.log(result instanceof Array && result.length === 2);
true
r2-p006 · Function declaration inside switch case capturing array constructor via closure
1switch (0) {
2 case 0:
3 function f() { return Array(1, 2); }
4 break;
5}
6const arr = f();
7console.log(arr.length === 2 && arr[0] === 1);
--- orig.js 2026-10-17 16:59:20.341950494 -0400 +++ fixed.js 2026-10-17 16:59:20.615954030 -0400 @@ -1,6 +1,6 @@ switch (0) { case 0: - function f() { return Array(1, 2); } + function f() { return [1, 2]; } break; } const arr = f();
r2-p007 · __proto__ assignment replacing Array instance with literal altering prototype chain expectations
1function Base() {}
2Base.prototype = Array(1); // becomes [1]
3const obj = new Base();
4console.log(obj.length === 1 && obj[0] === 1 && typeof obj.push === 'function');
false
r2-p008 · Name collision after hoisting due to var redeclaration in loop interacting with array constructor
1for (let i = 0; i < 1; i++) {
2 var xs = Array(1, 2);
3}
4console.log(xs.length === 2 && xs[0] === 1);
--- orig.js 2026-10-17 16:59:20.999958987 -0400 +++ fixed.js 2026-10-17 16:59:21.282962638 -0400 @@ -1,4 +1,4 @@ for (let i = 0; i < 1; i++) { - var xs = Array(1, 2); + var xs = [1, 2]; } console.log(xs.length === 2 && xs[0] === 1);
true