← Назад к вопросам

Как использовать map на псевдомассиве arguments?

2.0 Middle🔥 201 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Работа с 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:

  1. Array.prototype.map.call(arguments, fn) - классический
  2. Array.from(arguments).map(fn) - разборчиво
  3. [...arguments].map(fn) - современно
  4. function(...args) { args.map(fn) } - лучше всего

Рекомендация: Используй rest параметры ...args в определении функции - это проще и производительнее.