Об'єкт arguments
Подібний до масиву об'єкт arguments
описує аргументи, які було передано у функцію.
Синтаксис
arguments
Опис
Об'єкт arguments
— це локальна змінна, яка доступна всередині кожної функції. Цей об'єкт містить інформацію про кількість та значення всіх параметрів, що їх було передано до функції під час її виклику. Для читання чи змінювання значень аргументів можна скористатися синтаксисом доступу до елементів масиву, де індекс першого переданого аргументу починається з 0
.
Для прикладу, якщо в функцію передано три аргументи, звернутися до них можна так:
arguments[0]
arguments[1]
arguments[2]
Значення можна не лише читати, а й змінювати таким чином:
arguments[1] = 'new value';
Об'єкт arguments
не є масивом
. Він подібний до масиву, але не має жодних властивостей масиву, крім length (довжини). Наприклад, він не має методу pop. Проте його можна перетворити на справжній масив:
var args = Array.prototype.slice.call(arguments);
var args = [].slice.call(arguments);
Також можна скористатися методом Array.from()
або оператором розпакування, щоб перетворити arguments на справжній масив:
var args = Array.from(arguments);
// ES2015
var args = [...arguments];
Застосування методу slice
до arguments
заважає оптимізації в деяких рушіях JavaScript (наприклад, V8). Отже, якщо вас це обходить, створюйте новий масив шляхом перебору елементів псевдомасиву arguments. Можна також скористатися конструктором Array
як функцією:
var args = (arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments));
Об'єкт arguments
корисний в тих випадках, коли кількість аргументів функції заздалегідь невідома. Існує чимало прикладів того, коли функцію можна викликати із різною множиною аргументів, реалізуючи таким чином поведінку на кшталт «перевантаження», яке в чистому вигляді відсутнє в JavaScript. Очевидно, що така «перевантажена» функція не завше може задовольнитися переліком формальних аргументів однієї сигнатури (en-US). Саме тут arguments може стати в нагоді.
Завважте, що властивість arguments.length — це кількість фактичних (а не формальних) аргументів, які дійсно було передано до функції. Натомість для визначення кількості формальних параметрів, оголошених сигнатурою функції, скористайтесь властивістю Function.length.
Як свідчить typeof
, arguments
є об'єктом:
console.log(typeof arguments); // 'object'
Тип кожного окремого аргументу можна визначити за допомогою typeof та індексації псевдомасиву arguments
:
console.log(typeof arguments[0]); // значення typeof конкретного аргументу
Властивості
arguments.callee
- Посилання на функцію, що саме виконується.
arguments.caller
- Посилання на функцію, з якої здійснили виклик поточної (яка саме виконується).
arguments.length
- Кількість аргументів, що було фактично передано до функції.
arguments[@@iterator]
- Вертає новий ітератор масиву, що містить значення за кожним індексом в
arguments
.
Приклади
Функція, що з'єднує кілька рядків
В цьому прикладі наведно функцію, яка з'єднує кілька рядків в один. Єдиний формальний аргумент функції — це рядок, що виступатиме розділовою послідовністю символів між складовими, що підлягають з'єднуванню. Це можна втілити наступним чином:
function myJoin(separator) {
var args = Array.prototype.slice.call(arguments, 1);
return args.join(separator);
}
Отже, можна передавати довільну кількість аргументів, послідовність яких (окрім першого, що виступає розділовою послідовністю символів) перетворюється на масив, а тоді з'єднується за допомогою Array.join()
.
Отож маємо:
// вертає "камінь, ножиці, папір"
myJoin(", ", "камінь", "ножиці", "папір");
// вертає "я; дух; одвічна стихія; потопа"
myJoin("; ", "я", "дух", "одвічна стихія", "потопа");
// вертає "Чому Пінгвіни Живуть Зимою Без Своїх Фантазій"
myJoin(" ", "Чому", "Пінгвіни", "Живуть", "Зимою", "Без", "Своїх", "Фантазій");
Функція, що створює HTML-списки
В наступному прикладі наведено функцію, що створює HTML-розмітку списку. Єдиний формальний аргумент функції — текстовий рядок, що визначає різновид списку ("o" для впорядкованого списку, чи то пак — нумерованого, — або "u" для невпорядкованого). Решта аргументів, визначатиме власне елементи списку. Одна з можливих реалізацій виглядає наступним чином:
function list(type) {
var markup = "<" + type + "l>";
for (var i = 1; i < arguments.length; i++) {
markup += "<li>" + arguments[i] + "</li>";
}
markup += "</" + type + "l>";
return markup
}
До функції можна передати будь-яку кількість аргументів, створивши список з довільною кількістю елементів. Наприклад, так:
var markup = list("u", "Крижина", "Стежина", "Чужина");
console.log(markup); // виводить "<ul><li>Крижина</li><li>Стежина</li><li>Чужина</li><ul>"
Решта, типові та деструктуризовані параметри
Об'єкт arguments
можна використовувати в поєднанні з рештою, типовими (en-US) та деструктуризованими параметрами.
function foo(...args) {
return arguments;
}
foo(1, 2, 3); // вертає {"0": 1, "1": 2, "2": 3}
І хоча присутність решти, типових чи деструктуризованих параметрів не змінює поведінки об'єкта arguments в суворому режимі, в звичайному режимі все ж є невеличка різниця. За відсутності решти, типових чи деструктуризованих параметрів функція, яка виконується в звичайному (не в суворому) режимі, передбачає збереження зв'язку між значеннями формальних параметрів та значеннями, що їх містить об'єкт arguments
:
function foo(a) {
arguments[0] = 99; // змінюючи arguments[0] ми також змінюємо a
console.log(a);
}
foo(10); // 99
І навпаки:
function foo(a) {
a = 99; // змінюючи a ми також змінюємо arguments[0]
console.log(arguments[0]);
}
foo(10); // 99
Натомість, наявність таких (решти, типових чи деструктуризованих) параметрів той зв'язок порушує:
function foo(a = 55) {
arguments[0] = 99; // змінюючи arguments[0] ми більше не впливаємо на a
console.log(a);
}
foo(10); // 10
І навпаки:
function foo(a = 55) {
a = 99; // змінюючи a ми більше не впливаємо на arguments[0]
console.log(arguments[0]);
}
foo(10); // 10
Ба більше:
function foo(a = 55) {
console.log(arguments[0]);
}
foo(); // undefined
Ясна річ, цей зв'язок поширюється лише на значення змінних, а не на вміст об'єктів:
function foo(object = {}) {
object.value = 222;
console.debug(arguments[0].value);
}
foo({value: 111}); // Object {value: 222}
Специфікації
Специфікація | Статус | Коментар |
---|---|---|
ECMAScript 1st Edition (ECMA-262) | Standard | Первинне визначення. Реалізовано у JavaScript 1.1 |
ECMAScript 5.1 (ECMA-262) The definition of 'Arguments Object' in that specification. |
Standard | |
ECMAScript 2015 (6th Edition, ECMA-262) The definition of 'Arguments Exotic Objects' in that specification. |
Standard | |
ECMAScript (ECMA-262) The definition of 'Arguments Exotic Objects' in that specification. |
Living Standard |
Підтримка веб-переглядачами
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Basic support | (Yes) | (Yes) | (Yes) | (Yes) | (Yes) |
Feature | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
Basic support | (Yes) | (Yes) | (Yes) | (Yes) | (Yes) | (Yes) |