Как добавить элемент в массив с помощью метода push в JavaScript
Что проверяют
Вопрос простой, поэтому ответ «добавляет в конец» проверяют на глубину: знаете ли вы, что push мутирует массив и что он возвращает. Следом почти всегда идёт: «А как добавить элемент в массив в состоянии React?»
Как отвечать
Базовое поведение в трёх пунктах:
- что делает: добавляет один или несколько элементов в конец массива,
arr.push(4, 5); - что возвращает: новую длину массива, а не сам массив. Поэтому
arr = arr.push(x)превращает массив в число; - мутация: меняется исходный массив, ссылка остаётся прежней. Работает и с
const arr, потому чтоconstзапрещает переприсвоить переменную, а не менять содержимое.
Дальше покажите, где мутация важна. React сравнивает состояние по ссылке через Object.is: если сделать items.push(x) и передать тот же массив в setItems, React решит, что ничего не изменилось, и не перерисует компонент. Правильно создать новый массив: setItems(prev => [...prev, x]). Исключение: в редьюсерах Redux Toolkit работает Immer, и там state.list.push(x) допустим, потому что вы меняете черновик, а не настоящее состояние. Во Vue 3 push по реактивному массиву отслеживается прокси и перерисовку вызывает.
Альтернативы, которые стоит назвать:
[...arr, x]иarr.concat(x): возвращают новый массив, исходный не трогают;unshift: добавляет в начало, но сдвигает все индексы и на больших массивах медленнее;arr.push(...other): склеивает массивы на месте, но каждый элемент становится аргументом вызова, и на сотнях тысяч элементов можно получитьRangeError.
В ES2023 появились неизменяющие toSorted, toReversed, toSpliced и with, но пары для push среди них нет, тут по-прежнему используют spread.
Где спотыкаются
Думают, что push возвращает обновлённый массив, и строят на этом цепочку вызовов вроде arr.push(x).map(...).
Мутируют через push состояние React или пропсы, а потом ищут, почему интерфейс не обновился или обновился не в том компоненте.
Не знают, что push на замороженном через Object.freeze массиве бросает TypeError. Immer замораживает состояние стора, поэтому тот же push вне редьюсера на данных из Redux Toolkit падает.