Skip to main content

The arguments object

arguments is a built-in object, available inside any regular function (but not an arrow function), that holds every argument passed into that function at call time. It lets you work with the list of arguments even when no parameters are declared at all.

Theory

TL;DR

  • arguments is available only inside regular functions (function), not in arrow functions.
  • It is an array-like object: it has indexes and length, but no map, forEach or reduce.
  • It gives access to every argument passed, even when no parameters are declared.
  • In sloppy mode arguments and the parameters are linked: changing one changes the other.
  • Inside an arrow function, referring to arguments picks up the enclosing function's object, and if there is none you get a ReferenceError.
  • The modern, recommended replacement is rest parameters ...args.

Quick example

javascript
function showArguments() { console.log(arguments); } showArguments("apple", 42, true);

The console output:

text
[Arguments] { '0': 'apple', '1': 42, '2': true }

An array-like object, not an array

arguments looks like an array but is not one. It has:

  • indexes (0, 1, 2 and so on),
  • a length property,
  • but no array methods (map, forEach and the like).

To get a real array you have to convert it:

javascript
const args = Array.from(arguments); // or const args2 = [...arguments];

An example that reaches the arguments without declaring any parameters:

javascript
function sumAll() { let total = 0; for (let i = 0; i < arguments.length; i++) { total += arguments[i]; } return total; } console.log(sumAll(1, 2, 3, 4)); // 10

Here we declare no parameters and simply take whatever was passed through arguments.

As long as you do not change the values, the parameters and arguments show the same thing:

javascript
function show(a, b) { console.log(a, b); console.log(arguments[0], arguments[1]); } show("x", "y"); // a, b -> "x", "y" // arguments[0], arguments[1] -> "x", "y"

But in regular functions in sloppy mode they are linked: change one and the other changes too.

javascript
function demo(a) { console.log(a, arguments[0]); // 10, 10 a = 20; console.log(a, arguments[0]); // 20, 20 } demo(10);

This link does not work in strict mode ('use strict'), nor when the function has default parameters, a rest parameter or destructuring. So it is not something to rely on.

arguments inside arrow functions

javascript
const arrow = () => { console.log(arguments); // ReferenceError }; arrow(1, 2, 3);

Why:

  • Arrow functions do not create their own arguments object.
  • If you refer to it, the value is taken from the enclosing regular function, when there is one.

Visibly:

javascript
function outer() { const inner = () => console.log(arguments[0]); inner("ignored"); // "outer", because this is the outer function's arguments } outer("outer");

It is the same logic as with this: an arrow function has no this, no arguments, no super and no new.target of its own.

Rest parameters as the modern replacement

The modern and safe way instead of arguments is rest parameters:

javascript
function sumAll(...args) { return args.reduce((sum, n) => sum + n, 0); } console.log(sumAll(1, 2, 3)); // 6

The advantages of ...args over arguments:

  • It is a real array (it has .map, .filter, .reduce).
  • It works inside arrow functions.
  • There is no confusion about "linked" values.
  • The code reads cleaner and clearer.

A comparison:

Propertyarguments...rest
TypeArray-like objectArray
Array methods (map, forEach)NoYes
Available in arrow functionsNoYes
Linked to the parametersYes, in sloppy modeNo
Modern approachLegacyRecommended

An example worth remembering:

javascript
// The old way function oldSum() { return Array.from(arguments).reduce((a, b) => a + b); } // The new way const newSum = (...nums) => nums.reduce((a, b) => a + b); console.log(oldSum(1, 2, 3)); // 6 console.log(newSum(1, 2, 3)); // 6

Common mistakes

  • Calling array methods directly on arguments. arguments.map(...) throws a TypeError: you need Array.from(arguments) or [...arguments] first.
  • Expecting arguments inside an arrow function. It is not there, you get the enclosing function's value or a ReferenceError.
  • Relying on the link with the parameters. In strict mode, and whenever there are default values or a rest parameter, the link is gone.
  • Thinking arguments.length equals func.length. The first is the number of arguments actually passed, the second is the number of declared parameters before the first one with a default value.
  • Passing arguments along without copying it. That hinders engine optimizations and easily leads to non-obvious bugs; pass ...args instead.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.