Методы shift() и unshift()
Методы shift() и unshift() работают с началом массива: первый удаляет элемент, второй добавляет один или несколько элементов в начало. Понимание их поведения помогает предсказуемо изменять массивы и учитывать влияние на индексы и длину.
Массивы в JavaScript часто используются как удобная структура для хранения упорядоченных данных: списков задач, элементов интерфейса, событий, сообщений, товаров, кадров анимации и множества других последовательностей. Среди базовых операций над массивами особое место занимают методы shift() и unshift(). Они позволяют работать с началом массива: удалять первый элемент или добавлять элементы в начало. На первый взгляд эти методы кажутся простыми, но именно они помогают лучше понять, как устроены массивы, как ведёт себя их порядок и почему некоторые операции могут быть дороже по времени, чем ожидается.
Чтобы использовать shift и unshift осознанно, важно не ограничиваться механическим запоминанием их названий. Полезно понимать, что оба метода меняют исходный массив, как они влияют на индексы, что возвращают и в каких сценариях их применение оправдано. Эти знания помогают писать более предсказуемый код и избегать скрытых затрат производительности в больших коллекциях.
Что делают shift и unshift
shift()
Метод shift() удаляет первый элемент массива и возвращает его значение. После удаления все остальные элементы сдвигаются на одну позицию влево, то есть элемент, который был под индексом 1, становится новым первым элементом с индексом 0.
Пример:
const fruits = ['яблоко', 'банан', 'апельсин'];
const first = fruits.shift();
console.log(first); // 'яблоко'
console.log(fruits); // ['банан', 'апельсин']
Если массив пустой, shift() просто вернёт undefined и не вызовет ошибки. Это удобно при обработке очередей, где заранее неизвестно, есть ли ещё элементы.
unshift()
Метод unshift() добавляет один или несколько элементов в начало массива и возвращает новую длину массива. Все существующие элементы сдвигаются вправо, чтобы освободить место для новых значений.
Пример:
const fruits = ['банан', 'апельсин'];
const length = fruits.unshift('яблоко');
console.log(length); // 3
console.log(fruits); // ['яблоко', 'банан', 'апельсин']
В отличие от shift(), метод unshift() может добавить несколько значений сразу:
const list = [3, 4, 5];
list.unshift(1, 2);
console.log(list); // [1, 2, 3, 4, 5]
Краткое сравнение методов
| Метод | Действие | Что возвращает | Изменяет массив |
|---|---|---|---|
| shift() | Удаляет первый элемент | Удалённый элемент | Да |
| unshift() | Добавляет элементы в начало | Новую длину массива | Да |
Это простое сравнение помогает быстро запомнить основную разницу. Однако на практике важны не только результаты, но и побочные эффекты: изменение длины массива, пересчёт индексов и потенциальная нагрузка при работе с большими данными.
Как изменяется массив после операций
Поскольку оба метода работают с началом массива, они меняют структуру данных сильнее, чем кажется на первый взгляд. При удалении первого элемента все остальные смещаются на одну позицию. При добавлении в начало происходит обратное: элементы сдвигаются вправо.
Сдвиг индексов
Если массив выглядел так:
['a', 'b', 'c', 'd']
то после shift() он станет:
['b', 'c', 'd']
Индексы изменятся следующим образом:
'b'переместится с индекса1на0;'c'— с2на1;'d'— с3на2.
При unshift('x') в массиве:
['a', 'b', 'c']
получится:
['x', 'a', 'b', 'c']
Индексы всех старых элементов увеличатся на единицу.
Влияние на длину массива
Оба метода изменяют свойство length. После shift() длина уменьшается на 1, после unshift() — увеличивается на количество добавленных элементов.
Если обозначить исходную длину массива как L, то:
- после
shift()новая длина:L - 1; - после
unshift(a, b, c)новая длина:L + 3.
Такое изменение длины делает эти методы удобными для последовательной обработки данных, где важен текущий размер коллекции.
Где shift и unshift особенно полезны
Очереди
Классический сценарий — реализация очереди. Очередь работает по принципу FIFO: первым пришёл — первым вышел. В такой модели shift() используется для извлечения элемента из начала, а push() — для добавления в конец. Хотя задача статьи посвящена shift и unshift, полезно понимать, что именно они часто участвуют в построении очередей и обратных очередей.

Пример очереди:
const queue = ['задача 1', 'задача 2', 'задача 3'];
const current = queue.shift();
console.log(current); // 'задача 1'
console.log(queue); // ['задача 2', 'задача 3']
Стекоподобные или приоритетные сценарии
Если требуется временно поместить важный элемент в начало списка, удобен unshift(). Например, в интерфейсах или в обработке событий можно вставить срочную запись перед остальными. Этот метод полезен и в случаях, когда порядок должен быстро меняться без создания нового массива.
Работа с последовательностями
Методы часто применяются, когда нужно пошагово «снимать» элементы с начала списка или наращивать список с той же стороны. Это удобно в парсинге, при обходе очереди сообщений, при обработке буферов данных и в алгоритмах, где начало массива играет роль рабочей точки.
Примеры использования в реальном коде
Последовательная обработка элементов
const tasks = ['проверить почту', 'созвониться', 'отправить отчёт'];
while (tasks.length > 0) {
const task = tasks.shift();
console.log('Выполняется:', task);
}
Такой подход удобно использовать, когда нужен простой механизм постепенного извлечения данных. Однако при больших массивах может быть заметно снижение производительности, о чём стоит помнить.
Добавление важных элементов в начало
const timeline = ['событие 2', 'событие 3'];
timeline.unshift('событие 1');
console.log(timeline); // ['событие 1', 'событие 2', 'событие 3']
Этот приём помогает сохранить естественный порядок времени, когда новые данные должны оказаться в начале списка.
Добавление нескольких значений сразу
const numbers = [3, 4, 5];
numbers.unshift(1, 2);
console.log(numbers); // [1, 2, 3, 4, 5]
Добавление нескольких элементов за один вызов делает код компактным, особенно если новые значения уже подготовлены заранее.
Особенности и ограничения
Методы изменяют исходный массив
Важная особенность shift() и unshift() заключается в том, что они работают мутирующе. То есть исходный массив меняется прямо на месте. Это отличает их от методов, которые создают новый массив без изменения старого.
Если массив нужно сохранить в исходном виде, стоит заранее сделать копию:
const original = ['a', 'b', 'c'];
const copy = original.slice();
copy.shift();
console.log(original); // ['a', 'b', 'c']
console.log(copy); // ['b', 'c']
Удобство vs производительность
Для небольших массивов разница обычно несущественна. Но при больших объёмах данных повторяющееся использование shift() и unshift() может быть менее эффективным, чем операции с концом массива. Причина в том, что при изменении начала массива многие элементы приходится переиндексировать.
Если представить массив из n элементов, то при добавлении или удалении в начале может потребоваться перемещение значительной части элементов. Упрощённо это можно описать как затрату, связанную с количеством сдвигаемых позиций:
затраты ≈ количество перемещаемых элементов
На практике это означает, что для частых операций с большими объёмами данных иногда лучше выбирать другую структуру или иной способ организации хранения.
Сравнение с push и pop
Часто shift/unshift сравнивают с pop/push. У них похожая логика, но противоположная сторона массива:
- pop() удаляет последний элемент;
- push() добавляет элемент в конец;
- shift() удаляет первый элемент;
- unshift() добавляет элемент в начало.
Операции с концом массива обычно считаются более естественными для частых изменений, потому что не требуют массового сдвига индексов. Поэтому выбор между началом и концом массива зависит от логики задачи.
Практические нюансы работы с кодом
Проверка результата shift()
Поскольку shift() возвращает удалённый элемент, его часто удобно использовать прямо в присваивании:
const items = [10, 20, 30];
const firstItem = items.shift();
if (firstItem !== undefined) {
console.log('Удалён:', firstItem);
}
Если массив может быть пустым, полезно учитывать, что результатом станет undefined. Это особенно важно в условиях и циклах.
Проверка длины после unshift()
Метод unshift() возвращает новую длину массива. Иногда это удобно, если нужно сразу понять, сколько элементов теперь хранится в коллекции:
const arr = [2, 3];
const newLength = arr.unshift(1);
console.log(newLength); // 3
Однако в большинстве случаев длину можно прочитать и через arr.length, поэтому возвращаемое значение используется не всегда.
Работа с массивами и ссылками
Так как массивы в JavaScript являются объектами, переменные могут ссылаться на один и тот же массив. Если вызвать shift() или unshift() через одну ссылку, изменения увидят все другие переменные, указывающие на тот же массив.
const a = [1, 2, 3];
const b = a;
b.shift();
console.log(a); // [2, 3]
console.log(b); // [2, 3]
Этот момент нередко становится источником ошибок, если не учитывать, что массив не копируется автоматически.
Типичные ошибки при использовании
- Ожидание, что метод вернёт новый массив, хотя на самом деле он изменяет исходный.
- Забывание, что shift() возвращает элемент, а не массив.
- Предположение, что unshift() добавляет только одно значение, хотя можно передать несколько.
- Использование shift() в очень больших массивах без учёта возможной нагрузки.
- Игнорирование того, что индексы всех элементов после начала массива меняются.
Избежать этих ошибок помогает привычка явно проверять, что именно нужно: удалить первый элемент, вставить один элемент, вставить несколько элементов или сохранить исходный массив без изменений.
Когда лучше выбирать другие подходы
Если важна высокая скорость при частых вставках и удалениях в начале, массив может оказаться не лучшим инструментом. В таких случаях иногда используют более подходящие структуры данных или пересматривают алгоритм работы с коллекцией. Это не означает, что shift() и unshift() плохи сами по себе — они просто лучше подходят для задач, где операции с началом массива происходят не слишком часто или где удобство важнее предельной эффективности.
Также полезно оценивать, действительно ли нужно работать именно с началом массива. Иногда задачу можно сформулировать иначе, например, накапливать элементы в конце, а затем обрабатывать их в обратном порядке, если это соответствует логике сценария.
Сводная таблица для запоминания
| Ситуация | Подходящий метод | Почему |
|---|---|---|
| Нужно удалить первый элемент и получить его значение | shift() | Метод удаляет начало массива и возвращает удалённый элемент |
| Нужно добавить элемент в начало | unshift() | Метод вставляет значение перед всеми существующими элементами |
| Нужно добавить несколько элементов в начало | unshift() | Метод принимает несколько аргументов |
| Нужно сохранить массив без изменений | Ни один из этих методов напрямую | Оба метода мутируют массив, поэтому сначала нужна копия |
Итог
Shift() и unshift() — простые, но очень важные методы массивов в JavaScript. Первый удаляет элемент с начала и возвращает его, второй добавляет один или несколько элементов в начало и возвращает новую длину. Оба метода изменяют исходный массив, сдвигают индексы и могут быть менее удобны при больших объёмах данных, если операции выполняются слишком часто.
Знание этих особенностей помогает использовать массивы более точно: выбирать подходящий способ обработки очередей, аккуратно работать с порядком элементов и лучше понимать поведение кода в реальных сценариях. Чем яснее различие между началом и концом массива, тем проще строить надёжную и читаемую логику.