A function declares two parameters and gets handed five. What happens to the other three? They do not vanish: they sit in an automatic object, present in every classic function without anyone asking for it.
Definition
arguments is an object the engine creates on every call to a function declared with the function keyword. It holds every value received, in order, including those matching no declared parameter.
function total() {
console.log(arguments.length); // 3
console.log(arguments[0]); // 5
return Array.from(arguments).reduce((a, b) => a + b, 0);
}
console.log(total(5, 10, 15)); // 30The function declares no parameter yet works on three values. Before 2015, this was the only way to write a function taking a variable number of arguments.
An object that imitates an array without being one
This is mistake number one. The object has a length and numeric indexes, which is enough to create the illusion, but it inherits no array method whatsoever.
| Expression | Result |
|---|---|
arguments.length | Works |
arguments[0] | Works |
Array.isArray(arguments) | false |
arguments.map(...) | Error, no such method |
Turning it into a real array takes one line: Array.from(arguments), or [...arguments] with Spread (...). Both produce the same result.
An arrow function has no arguments object of its own. It uses the one from the surrounding function, and when there is none, the read fails with a reference error. That is deliberate: arrows were designed for neither this nor arguments.
What replaced it
Since 2015, the Rest (...) parameter does the same job better. It hands back a real array, it carries an explicit name, and it works inside arrow functions.
// The old way
function legacy() {
return Array.from(arguments).join(", ");
}
// Today's way, easier to read
const modern = (...values) => values.join(", ");
console.log(modern("a", "b")); // "a, b"One reason remains to know how it works: existing code. A codebase written before 2015 is full of it, and reading it correctly beats rewriting it blind.
Frequently asked questions
Why does arguments.map not work?
Because it is not an array, only an object that resembles one. No array method is available on it. Convert it first with Array.from(arguments), then chain the methods you need as usual.
Should it still be used in new code?
No. The Rest (...) parameter replaces it entirely, with a meaningful name and a real array at the end. Several linters flag it as outdated style. Keep it around only to understand older code.
What does it hold when a parameter has a default value?
Only what was actually passed at the call, never the defaults. A function with a default parameter, called with no argument, sees arguments.length at zero while the parameter itself carries its value. The two describe different things.