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

В чем разница между методами массива?

1.0 Junior🔥 161 комментариев
#JavaScript Core

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

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

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

Различия между методами массива в JavaScript

Есть множество методов работы с массивами в JavaScript. Они различаются по назначению, побочным эффектам, способу обработки элементов и изменению исходного массива. Разберём самые важные различия.

Мутирующие vs Немутирующие методы

Мутирующие методы изменяют исходный массив. Немутирующие методы возвращают новый массив и не меняют оригинал.

const numbers = [1, 2, 3, 4, 5];

// Мутирующие методы
numbers.push(6);        // Добавляет в конец, изменяет исходный
numbers.pop();          // Удаляет с конца, изменяет исходный
numbers.shift();        // Удаляет с начала, изменяет исходный
numbers.unshift(0);     // Добавляет в начало, изменяет исходный
numbers.splice(1, 2);   // Удаляет элементы, изменяет исходный
numbers.sort();         // Сортирует, изменяет исходный
numbers.reverse();      // Разворачивает, изменяет исходный

// Немутирующие методы
const doubled = numbers.map(n => n * 2);      // Новый массив
const evens = numbers.filter(n => n % 2 === 0); // Новый массив
const sliced = numbers.slice(1, 3);           // Новый массив
const concatenated = numbers.concat([6, 7]); // Новый массив

Функции высокого порядка vs Утилиты

Функции высокого порядка (map, filter, reduce, find) применяют функцию к каждому элементу. Утилиты (sort, reverse) работают со структурой массива.

const items = [{ id: 1, name: 'A' }, { id: 2, name: 'B' }];

// map — трансформирует каждый элемент
const names = items.map(item => item.name); // ['A', 'B']

// filter — отбирает элементы по условию
const filtered = items.filter(item => item.id > 1); // [{ id: 2, name: 'B' }]

// find — находит первый элемент по условию
const found = items.find(item => item.id === 2); // { id: 2, name: 'B' }

// findIndex — находит индекс элемента
const index = items.findIndex(item => item.id === 2); // 1

// includes — проверяет наличие элемента
const hasB = items.some(item => item.name === 'B'); // true

// reduce — агрегирует значения
const sum = [1, 2, 3].reduce((acc, n) => acc + n, 0); // 6

Основные методы и их отличия

map vs forEach

const numbers = [1, 2, 3];

// map — возвращает новый массив
const doubled = numbers.map(n => n * 2);
console.log(doubled); // [2, 4, 6]
console.log(numbers); // [1, 2, 3] — не изменился

// forEach — выполняет функцию для побочных эффектов
numbers.forEach(n => console.log(n * 2)); // Выводит 2, 4, 6
console.log(numbers); // [1, 2, 3] — не изменился
// forEach всегда возвращает undefined

filter vs find vs some vs every

const users = [
  { id: 1, active: true, age: 25 },
  { id: 2, active: false, age: 30 },
  { id: 3, active: true, age: 35 }
];

// filter — возвращает все элементы, соответствующие условию
const activeUsers = users.filter(u => u.active);
// [{ id: 1, active: true, age: 25 }, { id: 3, active: true, age: 35 }]

// find — возвращает ПЕРВЫЙ элемент
const firstActive = users.find(u => u.active);
// { id: 1, active: true, age: 25 }

// findIndex — возвращает индекс первого элемента
const firstIndex = users.findIndex(u => u.active);
// 0

// some — возвращает true, если ХОТЬ ОДИН элемент совпадает
const hasActive = users.some(u => u.active);
// true

// every — возвращает true, если ВСЕ элементы совпадают
const allActive = users.every(u => u.active);
// false

// includes — проверяет наличие примитивного значения
const nums = [1, 2, 3];
const hasToo = nums.includes(2);
// true

slice vs splice

const numbers = [1, 2, 3, 4, 5];

// slice — возвращает новый массив БЕЗ изменения исходного
const sliced = numbers.slice(1, 3); // [2, 3]
console.log(numbers); // [1, 2, 3, 4, 5] — не изменился

// splice — МУТИРУЕТ исходный массив и возвращает удалённые элементы
const spliced = numbers.splice(1, 2); // Удаляет 2 элемента с позиции 1
console.log(spliced);  // [2, 3] — удалённые элементы
console.log(numbers);  // [1, 4, 5] — массив изменился

// splice может добавлять элементы
const arr = [1, 2, 5];
arr.splice(2, 0, 3, 4); // Вставляет 3, 4 в позицию 2
console.log(arr); // [1, 2, 3, 4, 5]

reduce vs reduceRight vs flat vs flatMap

// reduce — агрегирует слева направо
const sum = [1, 2, 3, 4].reduce((acc, n) => acc + n, 0);
// ((((0 + 1) + 2) + 3) + 4) = 10

// reduceRight — агрегирует справа налево
const rightSum = [1, 2, 3, 4].reduceRight((acc, n) => acc + n, 0);
// ((((0 + 4) + 3) + 2) + 1) = 10

// Разница видна при порядке зависимых операций
const words = ['a', 'b', 'c'];
const left = words.reduce((acc, w) => acc + w); // 'abc'
const right = words.reduceRight((acc, w) => acc + w); // 'cba'

// flat — разворачивает вложенные массивы
const nested = [1, [2, 3], [4, [5, 6]]];
const flattened = nested.flat(1); // [1, 2, 3, 4, [5, 6]]
const deepFlat = nested.flat(Infinity); // [1, 2, 3, 4, 5, 6]

// flatMap — map + flat в один шаг
const doubled = [1, 2, 3].flatMap(n => [n, n * 2]);
// [1, 2, 2, 4, 3, 6]

Сортировка и разворот

const numbers = [3, 1, 4, 1, 5];

// sort — МУТИРУЕТ исходный массив
numbers.sort((a, b) => a - b);
console.log(numbers); // [1, 1, 3, 4, 5] — изменился

// Для немутирующей сортировки — используй slice
const sorted = [3, 1, 4, 1, 5]
  .slice()
  .sort((a, b) => a - b);

// reverse — МУТИРУЕТ исходный массив
const arr = [1, 2, 3];
arr.reverse();
console.log(arr); // [3, 2, 1] — изменился

// Немутирующий разворот
const reversed = [1, 2, 3]
  .slice()
  .reverse();
// или
const reversed2 = [...[1, 2, 3]].reverse();

Производительность

// forEach vs for — forEach медленнее из-за создания функции
const arr = new Array(1000000).fill(0);

// for — самый быстрый
for (let i = 0; i < arr.length; i++) {
  arr[i]++;
}

// forEach — медленнее
arr.forEach(el => el++);

// map — медленнее (создаёт новый массив)
const mapped = arr.map(el => el + 1);

Практические рекомендации

  1. Избегай мутирующих методов для функционального стиля
  2. Используй const с методами, возвращающими новые массивы
  3. Выбирай нужный метод:
    • Нужен новый массив? → map, filter, slice
    • Нужно изменить исходный? → push, pop, splice
    • Нужно найти элемент? → find, findIndex
    • Нужно проверить условие? → some, every, includes
    • Нужно объединить значения? → reduce, join
  4. Цепляй методы для читаемости: arr.filter().map().sort()
  5. Помни о производительности для больших массивов

Вывод

Выбор метода зависит от:

  • Нужно ли изменять исходный массив (мутирующий vs немутирующий)
  • Что возвращать (новый массив, одно значение, undefined)
  • Производительность и читаемость

В современном JavaScript рекомендуется использовать немутирующие методы для предсказуемого и безопасного кода.