Prefer Rest Parameters Over arguments

ID

javascript.prefer_rest_params

Severity

info

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Best Practice

Language

JavaScript

Tags

best-practice, modernization

Description

Reports any reference to the legacy arguments object inside a regular (non-arrow) function and recommends ES2015 rest parameters (function f(…​args) {}) instead. Arrow functions are not flagged because they do not bind their own arguments; any reference there resolves to the enclosing non-arrow function and is reported at that function instead.

Rationale

  • arguments is array-like but is not a real Array. Common operations such as .map, .filter, .forEach or .join require an explicit conversion (Array.from(arguments) or Array.prototype.slice.call(arguments)), which is noisy and easy to forget.

  • Using arguments prevents engine optimisations (inlining, escape analysis) and confuses static analysis tools and TypeScript.

  • It hides the function’s actual contract: a reader cannot tell from the parameter list how many arguments the function accepts.

  • Rest parameters (…​args) produce a real array, are explicit in the signature, work with destructuring and spread, and are the modern, documented way to write variadic functions.

// Bad
function sum() {
  return Array.from(arguments).reduce((a, b) => a + b, 0);
}

function logEach() {
  for (let i = 0; i < arguments.length; i++) {
    console.log(arguments[i]);
  }
}

Remediation

Replace arguments with a rest parameter. The rest parameter is a real array, so array methods work directly and the signature documents the variadic intent.

// Good
function sum(...numbers) {
  return numbers.reduce((a, b) => a + b, 0);
}

function logEach(...items) {
  for (const item of items) {
    console.log(item);
  }
}

If you only need the first few arguments, declare them as named parameters and use rest for the tail:

function withPrefix(prefix, ...rest) {
  return rest.map(x => prefix + x);
}