arguments is created for every call of a non-arrow function (unless a parameter is named arguments, or, with no parameter expressions, a body-level function or let/const is). It holds the arguments as passed, regardless of how many parameters are declared.
- Array-like, not an array. It has
length, index keys, andSymbol.iterator(the same function asArray.prototype.values), so spread andArray.fromwork. It inherits fromObject.prototype, somap,slice, and friends are missing, andArray.isArrayisfalse. - Mapped vs unmapped. In a sloppy function whose parameter list is simple (no defaults, rest, or destructuring),
arguments[i]is aliased to thei-th named parameter, in both directions, but only for indices below the number of arguments actually passed. In strict code or with a non-simple list it is a plain copy with no link. callee. Sloppy mapped objects expose the running function asarguments.callee. In unmapped objects it is a poison-pill accessor that throwsTypeError.- Arrows have none. Inside an arrow,
argumentsresolves to the enclosing function's.
Why avoid it: it isn't an array, the aliasing is surprising and only exists in legacy sloppy code, it hides a function's real signature, and rest parameters (...args) give a real array with explicit names. Reach for arguments only when you must read legacy code.