> Может ли при push в массив в JavaScript происходить копирование данных (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Avito
Стек: JavaScript
> Пример ответа
Короткий ответ
Нет, при push в массив в JavaScript копирования данных не происходит. Метод push добавляет новый элемент по индексу array.length и увеличивает длину массива на единицу. Сам объект массива хранит ссылки на элементы, а не их копии. При добавлении примитива сохраняется его значение, а при добавлении объекта - ссылка на него.
Подробное объяснение
Массивы в JavaScript - это динамические структуры данных, реализованные как объекты с числовыми ключами. При вызове push движок выполняет следующие шаги:
- Вычисляет текущую длину массива
length - Присваивает новое значение по ключу
length(например,arr[arr.length] = value) - Увеличивает
lengthна 1
Для примитивов (числа, строки, булевы значения, null, undefined, symbol, bigint) в массив записывается само значение. Для объектов - ссылка на объект в памяти. Никакого глубокого или поверхностного копирования данных не происходит.
Важно понимать: если вы push'ите объект, то в массиве хранится ссылка на тот же самый объект. Изменение объекта через любую ссылку отразится на всех местах, где эта ссылка хранится.
Исключение - typed arrays (Int32Array, Float64Array и т.д.), где данные хранятся в contiguous memory buffer, но там push не используется, так как размер фиксирован.
На практике
При работе с большими массивами или частыми операциями push важно помнить:
- push работает за амортизированное O(1) - в среднем константное время, но при превышении capacity может потребоваться переаллокация памяти с копированием всех существующих элементов в новый буфер (это внутренняя деталь реализации V8 и других движков, не влияющая на семантику кода)
- Если нужно избежать переаллокаций, можно заранее задать размер массива:
const arr = new Array(10000) - При push объекта в несколько массивов все они будут ссылаться на один и тот же объект - это частая причина багов при мутации данных
- Для создания независимой копии данных используйте
JSON.parse(JSON.stringify(obj)),structuredClone()или библиотеки вроде Immer
Пример кода
JAVASCRIPTconst arr = [1, 2, 3];const obj = { name: 'test' };arr.push(obj);console.log(arr[3] === obj); // true - это ссылка, не копияobj.name = 'changed';console.log(arr[3].name); // 'changed' - изменение отразилось// Для примитивовlet num = 42;arr.push(num);num = 100;console.log(arr[4]); // 42 - примитив скопирован по значению
Как отвечать на собеседовании
Начните с прямого ответа - нет, копирования не происходит. Затем объясните механизм: push просто присваивает значение по индексу и увеличивает length. Уточните разницу между примитивами (копируются по значению) и объектами (копируется ссылка). Если спросят про производительность, упомяните амортизированное O(1) и внутреннюю переаллокацию. Можно добавить, что в typed arrays push не применим, а в обычных массивах это просто синтаксический сахар над присваиванием.
Что проверяет интервьюер
- Понимание ссылочной модели JavaScript (примитивы vs объекты)
- Знание внутреннего устройства массивов (динамические, не фиксированного размера)
- Умение отличать семантику операции от её реализации (push не копирует, хотя движок может переаллоцировать память)
- Способность объяснить разницу между копированием ссылки и копированием значения
- Понимание, что push - это мутирующая операция, в отличие от concat или spread
Типичные ошибки
- Утверждение, что push всегда создаёт копию данных - это неверно, он работает с оригиналом
- Путаница между копированием ссылки и глубоким копированием объекта
- Мысль, что push для примитивов тоже сохраняет ссылку - примитивы immutable и передаются по значению
- Предположение, что push работает за O(n) из-за копирования - на самом деле амортизированное O(1)
- Использование push с typed arrays - там нет такого метода, нужно использовать индексацию
> Похожие задачи по frontend
Что делать в функции каррирования в JavaScript при получении достаточного количества аргументов
Блокируется ли поток при выполнении асинхронного кода после синхронного в JavaScript
Есть ли внутренние механизмы выделения памяти при добавлении элементов в массив в JavaScript
Можно ли использовать массив или объект для хранения уникальных значений в JavaScript
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью