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

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

1.6 Junior🔥 111 комментариев
#JavaScript Core

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

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

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

Использование reduce на псевдомассиве arguments

Объект arguments — это специальный объект, доступный внутри функций, который содержит все переданные аргументы. Хотя это не настоящий массив, он имеет числовые индексы и свойство length, что позволяет работать с ним как с массивом. Рассмотрю несколько способов использования reduce с arguments.

Проблема: arguments — это не массив

// arguments не является обычным массивом
function sum(a, b, c) {
  console.log(arguments instanceof Array); // false
  console.log(typeof arguments); // "object"
  console.log(arguments.length); // 3
  // arguments.reduce() // Ошибка: undefined is not a function
}

sum(1, 2, 3);

Решение 1: Преобразовать arguments в массив с Array.from()

function sumAll() {
  // Преобразуем arguments в настоящий массив
  const args = Array.from(arguments);
  
  // Теперь можем использовать reduce
  const total = args.reduce((sum, value) => sum + value, 0);
  return total;
}

console.log(sumAll(1, 2, 3, 4, 5)); // 15

Практический пример — функция, умножающая все аргументы:

function multiply() {
  return Array.from(arguments).reduce((product, num) => product * num, 1);
}

console.log(multiply(2, 3, 4)); // 24

Решение 2: Использовать spread оператор (...)

Это более современный и более читаемый способ:

function sumAll(...args) {
  // args уже настоящий массив
  return args.reduce((sum, value) => sum + value, 0);
}

console.log(sumAll(10, 20, 30)); // 60

Отличие от arguments: Spread оператор автоматически преобразует параметры в массив, что исключает проблемы с pseudoarray.

function processData(...values) {
  // values — настоящий массив
  return values.reduce((acc, curr) => {
    return { ...acc, [curr]: curr * 2 };
  }, {});
}

console.log(processData('a', 'b', 'c')); // { a: 2, b: 4, c: 6 }

Решение 3: Использовать Array.prototype.slice.call()

Старый способ, работает везде, но менее читаемый:

function sumAll() {
  // Используем slice() для преобразования
  const args = Array.prototype.slice.call(arguments);
  return args.reduce((sum, value) => sum + value, 0);
}

console.log(sumAll(5, 10, 15)); // 30

Решение 4: Вызвать reduce напрямую через call()

Можно вызвать reduce напрямую на arguments, используя call():

function sumAll() {
  // Вызываем reduce() в контексте arguments
  return Array.prototype.reduce.call(arguments, (sum, value) => sum + value, 0);
}

console.log(sumAll(2, 4, 6, 8)); // 20

Практические примеры

Функция с начальным значением:

function calculateWithInitial(initial) {
  // Первый аргумент — начальное значение, остальные — числа
  const numbers = Array.from(arguments).slice(1);
  return numbers.reduce((acc, num) => acc + num, initial);
}

console.log(calculateWithInitial(100, 10, 20, 30)); // 160

Функция для конкатенации строк:

function concatenate() {
  return Array.from(arguments).reduce((result, str) => {
    return result + (result ? ' ' : '') + str;
  }, '');
}

console.log(concatenate('Hello', 'World', 'from', 'JavaScript')); 
// "Hello World from JavaScript"

Функция для поиска максимума:

function findMax() {
  if (arguments.length === 0) return null;
  
  return Array.from(arguments).reduce((max, current) => {
    return current > max ? current : max;
  });
}

console.log(findMax(5, 12, 3, 8, 1)); // 12

Функция для подсчёта частоты элементов:

function countOccurrences() {
  return Array.from(arguments).reduce((counts, item) => {
    counts[item] = (counts[item] || 0) + 1;
    return counts;
  }, {});
}

console.log(countOccurrences('a', 'b', 'a', 'c', 'a', 'b'));
// { a: 3, b: 2, c: 1 }

Сравнение методов

function testMethods() {
  // Способ 1: Array.from()
  const sum1 = Array.from(arguments).reduce((a, b) => a + b, 0);
  
  // Способ 2: slice().call()
  const sum2 = Array.prototype.reduce.call(arguments, (a, b) => a + b, 0);
  
  // Способ 3: напрямую на arguments
  const sum3 = [].reduce.call(arguments, (a, b) => a + b, 0);
  
  console.log(sum1, sum2, sum3); // Все дают одинаковый результат
}

testMethods(1, 2, 3, 4, 5);

Когда использовать arguments vs spread оператор

arguments:

  • Устаревший подход
  • Работает везде, включая очень старые браузеры
  • Менее удобен для работы
// Старый стиль
function oldStyle() {
  const args = Array.from(arguments);
  // ...
}

Spread оператор (...):

  • Современный, рекомендуемый подход
  • Более читаемый код
  • Лучше работает с инструментами статического анализа
// Новый стиль
function newStyle(...args) {
  // args уже массив
  // ...
}

Сложный пример: комбинирование с filter

function sumEvenNumbers() {
  return Array.from(arguments)
    .filter(num => num % 2 === 0)
    .reduce((sum, num) => sum + num, 0);
}

console.log(sumEvenNumbers(1, 2, 3, 4, 5, 6)); // 12 (2 + 4 + 6)

Выводы

  • arguments — это объект, а не массив, поэтому нужно его преобразовать
  • Используй Array.from(arguments) или [].slice.call(arguments) для преобразования
  • Лучше использовать spread оператор ...args в новых проектах
  • С преобразованным массивом reduce() работает как обычно
  • Помни о начальном значении в reduce() для корректных результатов
Как использовать reduce на псевдомассиве arguments? | PrepBro