Как использовать map на псевдомассиве arguments?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Работа с map() на псевдомассиве arguments
Псевдомассив arguments доступен только в обычных функциях и технически не является массивом. Есть несколько способов использовать map() с ним.
Что такое arguments?
arguments - это специальный объект внутри каждой функции:
function test() {
console.log(arguments);
console.log(typeof arguments); // 'object'
console.log(Array.isArray(arguments)); // false
}
test('a', 'b', 'c');
// {
// '0': 'a',
// '1': 'b',
// '2': 'c',
// length: 3 // <- есть length, как у массива
// }
Проблема: arguments не имеет методов массива (map, filter, reduce и т.д.).
Способ 1: Array.prototype.map.call()
Позволяет использовать метод Array на любом объекте с length:
function sum() {
// Используем map на arguments
const numbers = Array.prototype.map.call(arguments, Number);
console.log(numbers); // [1, 2, 3]
return numbers.reduce((a, b) => a + b, 0);
}
sum('1', '2', '3'); // 6
Как это работает:
Array.prototype.map.call(arguments, callback)
^
Используем массивный метод map
на объекте arguments
Способ 2: Array.prototype.map.apply()
То же самое, но через apply:
function greet() {
const args = Array.prototype.map.apply(arguments, [
function(name) { return 'Hello, ' + name; }
]);
console.log(args);
}
greet('John', 'Jane');
// ['Hello, John', 'Hello, Jane']
Способ 3: Array.from() - самый простой
Преобразовать в реальный массив, потом использовать map:
function test() {
const args = Array.from(arguments);
return args.map(x => x * 2);
}
test(1, 2, 3); // [2, 4, 6]
Способ 4: Spread оператор - самый современный
Ещё проще с ...:
function test() {
const args = [...arguments];
return args.map(x => x * 2);
}
test(1, 2, 3); // [2, 4, 6]
Способ 5: Сразу использовать параметры функции (рекомендуется)
Вместо arguments используй rest параметры:
// Старый способ (плохо)
function old() {
Array.prototype.map.call(arguments, x => x * 2);
}
// Современный способ (хорошо)
function modern(...args) {
return args.map(x => x * 2);
}
modern(1, 2, 3); // [2, 4, 6]
Практические примеры
Пример 1: Преобразование строк в числа
function parseNumbers() {
return Array.prototype.map.call(arguments, Number);
}
parseNumbers('1', '2', '3.5');
// [1, 2, 3.5]
Пример 2: Умножение всех аргументов
function multiplyAll() {
return Array.prototype.map.call(arguments, x => x * 2).reduce((a, b) => a + b);
}
multiplyAll(10, 20, 30);
// 120 (10*2 + 20*2 + 30*2)
Пример 3: Логирование всех аргументов
function logArgs() {
Array.prototype.map.call(arguments, (arg, index) => {
console.log(`Arg ${index}: ${arg}`);
});
}
logArgs('hello', 42, true);
// Arg 0: hello
// Arg 1: 42
// Arg 2: true
Пример 4: Фильтр и map вместе
function filterAndMap() {
return Array.prototype.filter
.call(arguments, x => x > 0)
.map(x => x * 2);
}
filterAndMap(1, -5, 3, -2, 4);
// [2, 6, 8]
Сравнение способов
function example() {
// Способ 1: Array.prototype.map.call()
const a = Array.prototype.map.call(arguments, x => x * 2);
// Способ 2: Array.from()
const b = Array.from(arguments).map(x => x * 2);
// Способ 3: Spread оператор
const c = [...arguments].map(x => x * 2);
// Способ 4: Rest параметры (рекомендуется)
// function example(...args) - в определении функции
// Все способы дают: [2, 4, 6]
}
example(1, 2, 3);
Таблица методов
Метод Браузеры Читаемость Производ.
Array.prototype.map.call() Все Низкая Отличная
Array.from().map() IE11+ Средняя Хорошая
[...arguments].map() Modern Хорошая Нормально
...args rest параметры Modern Отличная Лучшая
Производительность
// Тест на 1M элементов
// Array.prototype.map.call() - БЫСТРО, нет копирования
Array.prototype.map.call(arguments, fn); // ~100ms
// Array.from() - копирует массив
Array.from(arguments).map(fn); // ~200ms
// Spread оператор - копирует массив
[...arguments].map(fn); // ~150ms
Когда что использовать?
Если нужна максимальная совместимость:
Array.prototype.map.call(arguments, callback);
Если нужна читаемость:
Array.from(arguments).map(callback);
Если нужна современность:
[...arguments].map(callback);
Если реально нужна производительность (рекомендуется):
// В самом определении функции
function test(...args) {
return args.map(callback);
}
Почему rest параметры лучше?
// Старый способ (плохо)
function old() {
// arguments - от браузера, сложно оптимизировать
// this зависит от контекста вызова
// arguments нет в arrow functions
// arguments доступен только в function() {}, не в () => {}
}
// Современный способ (хорошо)
function modern(...args) {
// args - обычный массив, легко оптимизировать
// this не влияет
// работает везде
// работает даже в arrow functions
return args.map(...);
}
Arrow функции
В arrow функциях arguments не работает:
// Не работает
const arrow = () => {
console.log(arguments); // ReferenceError
};
// Используй rest параметры
const arrow = (...args) => {
return args.map(x => x * 2);
};
arrow(1, 2, 3); // [2, 4, 6]
Резюме
Способы использовать map на arguments:
Array.prototype.map.call(arguments, fn)- классическийArray.from(arguments).map(fn)- разборчиво[...arguments].map(fn)- современноfunction(...args) { args.map(fn) }- лучше всего
Рекомендация: Используй rest параметры ...args в определении функции - это проще и производительнее.