Skip to main content

Об'єкт arguments

arguments це вбудований об'єкт, доступний усередині будь-якої звичайної функції (але не стрілкової), який містить усі аргументи, передані в цю функцію при виклику. Він дозволяє працювати зі списком аргументів навіть тоді, коли параметри взагалі не оголошені.

Теорія

TL;DR

  • arguments доступний лише всередині звичайних функцій (function), не у стрілкових.
  • Це псевдомасив: є індекси і length, але немає map, forEach, reduce.
  • Дає доступ до всіх переданих аргументів, навіть якщо параметри не оголошені.
  • У нестрогому режимі arguments і параметри пов'язані: зміна одного змінює інше.
  • У стрілковій функції звернення до arguments бере його із зовнішньої функції, а якщо такої немає, буде ReferenceError.
  • Сучасна і рекомендована заміна це rest параметри ...args.

Швидкий приклад

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

Результат у консолі:

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

Псевдомасив, а не масив

arguments виглядає як масив, але ним не є. У нього є:

  • індекси (0, 1, 2 і далі),
  • властивість length,
  • але немає методів масиву (map, forEach і подібних).

Щоб отримати справжній масив, його треба сконвертувати:

javascript
const args = Array.from(arguments); // або const args2 = [...arguments];

Приклад із доступом до аргументів без оголошених параметрів:

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

Тут ми не оголошуємо параметрів, а просто беремо все, що передано, через arguments.

Відмінність від параметрів і їхній зв'язок

Поки значення не змінюють, параметри й arguments показують те саме:

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"

Але у звичайних функціях у нестрогому режимі вони пов'язані: змінюється одне, змінюється й інше.

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

Цей зв'язок не працює у строгому режимі ('use strict'), а також якщо у функції є параметри за замовчуванням, rest параметр або деструктуризація. Тому покладатися на нього не варто.

arguments у стрілкових функціях

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

Чому так:

  • Стрілкові функції не створюють власного об'єкта arguments.
  • Якщо звернутися до нього, значення візьметься із зовнішньої звичайної функції, якщо вона є.

Наочно:

javascript
function outer() { const inner = () => console.log(arguments[0]); inner("ignored"); // "outer", бо це arguments зовнішньої функції } outer("outer");

Це та сама логіка, що і з this: стрілкова функція не має ні власного this, ні arguments, ні super, ні new.target.

Rest параметри як сучасна заміна

Сучасний і безпечний спосіб замість arguments це rest параметри:

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

Переваги ...args над arguments:

  • Це справжній масив (є .map, .filter, .reduce).
  • Працює у стрілкових функціях.
  • Немає плутанини з «пов'язаними» значеннями.
  • Код виглядає чистіше й зрозуміліше.

Порівняння:

Властивістьarguments...rest
ТипПсевдомасивМасив
Методи масиву (map, forEach)НемаєЄ
Доступний у стрілкових функціяхНіТак
Пов'язаний з параметрамиТак, у нестрогому режиміНі
Сучасний спосібЗастарілийРекомендований

Приклад для запам'ятовування:

javascript
// Старий спосіб function oldSum() { return Array.from(arguments).reduce((a, b) => a + b); } // Новий спосіб const newSum = (...nums) => nums.reduce((a, b) => a + b); console.log(oldSum(1, 2, 3)); // 6 console.log(newSum(1, 2, 3)); // 6

Типові помилки

  • Викликати методи масиву прямо на arguments. arguments.map(...) кине TypeError: спочатку потрібен Array.from(arguments) або [...arguments].
  • Очікувати arguments у стрілковій функції. Його там немає, буде значення зовнішньої функції або ReferenceError.
  • Покладатися на зв'язок з параметрами. У строгому режимі, а також за наявності значень за замовчуванням чи rest параметра, зв'язку немає.
  • Думати, що arguments.length дорівнює func.length. Перше це кількість фактично переданих аргументів, друге це кількість оголошених параметрів до першого зі значенням за замовчуванням.
  • Передавати arguments далі без копіювання. Це заважає оптимізаціям рушія і легко призводить до неочевидних багів; передавайте ...args.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.