Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Об'єкт arguments». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`arguments` це вбудований псевдомасив, доступний усередині будь-якої звичайної функції, який містить усі аргументи, передані під час виклику.** Він має індекси і `length`, але не має методів масиву (`map`, `filter`, `reduce`). Стрілкові функції власного `arguments` не створюють: звернення до нього візьме `arguments` із зовнішньої звичайної функції, а якщо такої немає, буде `ReferenceError`. Сучасна заміна це rest параметри. ```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 ``` **Ключове:** `...args` це справжній масив, він працює і в стрілкових функціях, тому `arguments` сьогодні вважають застарілим.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**`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`.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.