Suggest an editImprove this articleRefine the answer for “What is arguments pseudo-Array in JavaScript”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**arguments** is an array-like object inside regular JavaScript functions that collects all passed arguments by index. ```javascript function sum() { return Array.from(arguments).reduce((a, b) => a + b, 0); } sum(1, 2, 3); // 6 ``` **Key:** has indices and `length` but no Array methods. Arrow functions don't have own `arguments`. Use rest params (`...args`) in new code.Shown above the full answer for quick recall.Answer (EN)Image**arguments** is a function-local object in regular (non-arrow) JavaScript functions that automatically collects all passed arguments into an indexed, array-like structure. ## Theory ### TL;DR - Like a cashier's bag that collects everything handed over, even extras you never named - Array-like (has indices + `length`) but is an `Object`, not an `Array` - no `.map()` or `.forEach()` - In strict mode, the live link between `arguments[i]` and named params is disabled - Arrow functions don't have their own `arguments`; they inherit from the outer scope - Decision: use rest params (`...args`) in all new code; `arguments` only for legacy or IE11 contexts ### Quick example ```javascript function greet(name, age) { console.log(arguments[0]); // "Alice" - access by index console.log(arguments.length); // 3 - counts all, even extras console.log(Array.isArray(arguments)); // false - not a real Array } greet("Alice", 30, "NYC"); ``` Three arguments were passed but only two were declared. `arguments.length` shows 3 - it captures everything, not just the named ones. ### Key difference `arguments` works like an array for basic access (`arguments[0]`, `arguments.length`) but is an `Object` without Array prototype methods. Calling `arguments.forEach(...)` throws a TypeError. To use array operations, convert first: `Array.from(arguments)` or `[...arguments]`. The design saves memory for simple indexed lookups but adds an extra step when you need filtering or mapping. ### When to use - Legacy browser support (IE11 or untranspiled environments): `arguments` works without polyfills - Quick debug logging: `console.log(arguments)` shows all inputs in one call - Dynamic argument count in older utility code that predates rest params - New code: always reach for `...args`; it gives a real Array with no conversion needed ### How the engine handles this In V8 (Chrome and Node.js), when a regular function executes, the engine creates an `Arguments` exotic object on the call stack. In non-strict mode, it maps `arguments[i]` directly to the corresponding named parameter through a hidden parameter map with getters and setters. Change `a` inside the function and `arguments[0]` updates too. Strict mode disables this link entirely - named params and `arguments[i]` become independent copies. Arrow functions skip `arguments` creation and inherit from the enclosing scope. ### Common mistakes **Calling array methods directly:** ```javascript function sum() { let total = 0; arguments.forEach(x => total += x); // TypeError: arguments.forEach is not a function } ``` Fix: `Array.from(arguments).forEach(...)` or switch to rest params. **Expecting arrow functions to have `arguments`:** ```javascript const fn = () => console.log(arguments); // ReferenceError or outer scope's arguments ``` Fix: `const fn = (...args) => console.log(args);` **Unexpected parameter aliasing in non-strict mode:** ```javascript function add(a, b) { arguments[0] = 100; return a + b; // Returns 140, not 42 - a changed with arguments[0] } add(2, 40); ``` Changing `arguments[i]` also changes the named param. Adding `'use strict'` breaks that link. **Strict mode confusion:** ```javascript 'use strict'; function fn(a) { a = 2; console.log(arguments[0]); // Still 1 - no live mapping in strict mode } fn(1); ``` ### Real-world usage - Express.js (pre-ES6): route handlers inspected `arguments` for dynamic middleware chains - jQuery: legacy event handlers read `arguments` for extra event data in plugins - Lodash: utility functions converted `arguments` internally for variadic input - Pre-ES6 conversion pattern: `Array.prototype.slice.call(arguments)` before `Array.from` existed | Feature | `arguments` | Rest params (`...args`) | |---|---|---| | Type | Object | Array | | Array methods | No (convert first) | Yes | | Strict mode mapping | Disabled | N/A | | Arrow functions | Inherited, not own | Yes | | New code | No | Yes | ### Follow-up questions **Q:** Why isn't `arguments` a real Array? **A:** Memory optimization. The engine skips allocating a full Array object for simple indexed access. You only convert when you need array methods. **Q:** What changes in strict mode? **A:** The live parameter map is disabled. Changing a named param no longer updates `arguments[i]`, and vice versa. They are independent after the function starts. **Q:** Can you use `arguments` in arrow functions? **A:** No own `arguments` is created. If you reference it inside an arrow, you get the outer regular function's `arguments`, or a ReferenceError if there's no enclosing regular function. **Q:** How to convert `arguments` to an array in pre-ES6 code? **A:** `Array.prototype.slice.call(arguments)` was the standard before `Array.from` and spread syntax. **Q:** In V8, when is the parameter map for `arguments` created? **A:** On function entry, for non-strict regular functions. It has getters and setters linking `arguments` properties to parameter slots. Strict mode and arrow functions skip it to prevent aliasing bugs. ## Examples ### Basic: summing any number of values ```javascript function sum() { let total = 0; for (let i = 0; i < arguments.length; i++) { total += arguments[i]; } return total; } console.log(sum(1, 2, 3)); // 6 console.log(sum(10, 20)); // 30 ``` No parameters declared, but the function handles any count. `arguments.length` drives the loop. This is the classic pattern you'll find in pre-ES6 utility libraries. ### Intermediate: legacy middleware logger ```javascript // Pre-ES6 Express-style logger - still found in older codebases function logRequest() { var args = Array.from(arguments); console.log('Received ' + args.length + ' args:', args); // args[0] = path, args[1] = handler, rest = middleware fns } logRequest('/users', handler, authMiddleware, rateLimiter); // Received 4 args: ['/users', fn, fn, fn] ``` `Array.from` converts `arguments` to a real array before any array operations. I've seen this exact pattern in Express codebases from 2014-2016 that were never updated - it still runs, but rest params make the intent clearer.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.