Avatar ·

Как расширить существующий массив другим массивом в JavaScript без создания нового?

Всем привет! Я только начал изучать JavaScript и столкнулся с такой проблемой. У меня есть два массива: ```javascript let fruits = ['apple', 'banana', 'orange']; let moreFruits = ['grape', 'kiwi', 'mango']; ``` Мне нужно добавить элементы из массива `moreFruits` в конец массива `fruits`, чтобы получить в итоге один массив `['apple', 'banana', 'orange', 'grape', 'kiwi', 'mango']`. Я знаю, что можно сделать так: ```javascript let combined = fruits.concat(moreFruits); // ['apple', 'banana', 'orange', 'grape', 'kiwi', 'mango'] ``` Но проблема в том, что `concat()` создаёт **новый** массив, а мне нужно изменить именно **существующий** массив `fruits`, не создавая новый. Почему это важно? Потому что в моём коде на массив `fruits` ссылаются несколько переменных и функций, и если я создам новый массив, все эти ссылки потеряются. Я пробовал использовать `push()` в цикле: ```javascript for (let i = 0; i < moreFruits.length; i++) { fruits.push(moreFruits[i]); } ``` Это работает, но выглядит громоздко. Есть ли более элегантный способ? Может быть, какой-то метод вроде `fruits.pushAll(moreFruits)` или что-то подобное? Заранее спасибо за помощь! <<>>

Используйте push() с оператором spread (ES6+)

Самый современный и элегантный способ — использовать метод push() вместе с оператором расширения (spread operator) .... Этот подход появился в ES6 (ECMAScript 2015) и позволяет «развернуть» элементы второго массива прямо в аргументы метода push().

let fruits = ['apple', 'banana', 'orange'];
let moreFruits = ['grape', 'kiwi', 'mango'];

fruits.push(...moreFruits);

console.log(fruits); // ['apple', 'banana', 'orange', 'grape', 'kiwi', 'mango']
console.log(fruits.length); // 6 — массив был изменён на месте

Как это работает: оператор ... «разворачивает» массив moreFruits в отдельные элементы. Фактически вызов fruits.push(...moreFruits) эквивалентен fruits.push('grape', 'kiwi', 'mango'). При этом push() изменяет оригинальный массив fruits, а не создаёт новый.

Почему это лучший вариант?

  • Производительность: push() с spread работает быстро для массивов среднего размера. Для очень больших массивов (сотни тысяч элементов) может быть небольшая задержка из-за разворачивания, но в 99% случаев это незаметно.
  • Читаемость: Код короткий и понятный — сразу видно, что вы добавляете элементы одного массива в другой.
  • Мутация: Массив fruits изменяется на месте, все ссылки на него остаются валидными.

Альтернатива: apply() (для старых браузеров)

Если вам нужно поддерживать очень старые версии JavaScript (до ES6), можно использовать Function.prototype.apply():

let fruits = ['apple', 'banana', 'orange'];
let moreFruits = ['grape', 'kiwi', 'mango'];

Array.prototype.push.apply(fruits, moreFruits);
// или короче:
fruits.push.apply(fruits, moreFruits);

console.log(fruits); // ['apple', 'banana', 'orange', 'grape', 'kiwi', 'mango']

Метод apply() принимает массив аргументов и передаёт их в функцию push() как отдельные параметры. Работает аналогично spread, но синтаксис более громоздкий.

Важное предостережение

Не пытайтесь использовать fruits.push(moreFruits) без spread — это добавит массив как один элемент, а не его содержимое:

let fruits = ['apple', 'banana'];
fruits.push(['grape', 'kiwi']);
console.log(fruits); // ['apple', 'banana', ['grape', 'kiwi']] — не то, что нужно!

Когда использовать concat()?

Метод concat() всё ещё полезен, когда вам нужно создать новый массив, не затрагивая исходные. Например, в функциональном программировании или при работе с иммутабельными данными (React state). Но для мутации существующего массива — push(...) или push.apply() — ваш выбор.

<<>>

Используйте splice() для вставки в середину

Метод splice() позволяет не только добавлять элементы в конец массива, но и вставлять их в любую позицию. Если вам нужно расширить массив не в конец, а, например, в начало или середину, splice() с оператором spread — отличное решение.

let fruits = ['apple', 'banana', 'orange'];
let moreFruits = ['grape', 'kiwi'];

// Вставить в начало (индекс 0, удалить 0 элементов)
fruits.splice(0, 0, ...moreFruits);
console.log(fruits); // ['grape', 'kiwi', 'apple', 'banana', 'orange']

// Вставить после первого элемента (индекс 1)
fruits.splice(1, 0, ...moreFruits);
console.log(fruits); // ['apple', 'grape', 'kiwi', 'banana', 'orange']

Синтаксис: array.splice(start, deleteCount, ...items). Первый аргумент — индекс, с которого начинаем изменения. Второй — сколько элементов удалить (0, если только вставляем). Третий и далее — элементы для вставки. Оператор spread разворачивает массив как отдельные аргументы.

Плюсы: универсальность — можно вставлять в любое место. Минусы: для простого добавления в конец push() читается лучше и работает быстрее (особенно на больших массивах, так как splice() может вызывать переиндексацию).

Также помните: splice(), как и push(), изменяет исходный массив. Если нужно просто добавить в конец — используйте push(...) из первого ответа. splice() приберегите для случаев, когда позиция вставки отличается от конца.