No Sparse Arrays

ID

javascript.no_sparse_arrays

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

JavaScript

Tags

reliability, suspicious-array

Description

Reports array literals that contain at least one elided element (a hole). A hole is what [1, , 3] produces between the two commas — the slot has no value at all, not even undefined. Common forms:

  • Interior hole: [1, , 3]

  • Leading hole: [, 1, 2]

  • Multiple holes: [1, , , 4]

  • Trailing hole: [1, 2, ,] (the second comma after 2 introduces a third, elided slot)

A simple trailing comma without a hole — e.g. [1, 2, 3,] — is not reported. That is a length-3 dense array.

Rationale

  • Array methods treat holes inconsistently. forEach, for…of and Array.from visit a hole as undefined; map, filter, every, some, and the for (let i = 0; i < arr.length; i++) form skip it. The same array therefore behaves differently depending on which method runs.

  • arr.length counts holes, so [1, , 3].length === 3, but the second slot is not enumerable. Logic that pairs length with arr[i] reads undefined and silently produces wrong results.

  • In the vast majority of real code, a hole is a typo from a stray comma. If undefined is intended, it should be written explicitly — [1, undefined, 3] — so readers and tools see the same value.

// Bad
const days = [
  "Monday",
  "Tuesday",
  ,                 // typo — produces a hole, not "Wednesday"
  "Thursday"
];
days.forEach(d => console.log(d.toUpperCase()));   // throws on the hole

Remediation

Remove the stray comma, or use an explicit undefined (or null) where the slot is intentionally empty.

// Good
const days = [
  "Monday",
  "Tuesday",
  undefined,
  "Thursday"
];