> Вернёт ли метод map в JavaScript новый массив с новыми объектами или с теми же старыми объектами при добавлении свойства к объектам? (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Домклик
Стек: JavaScript
> Пример ответа
Короткий ответ
map вернёт новый массив, но объекты внутри останутся теми же самыми ссылками. Добавление свойства к объекту внутри колбэка изменит исходный объект, так как map не создаёт глубокую копию элементов. Новым будет только сам массив, а не его содержимое.
Подробное объяснение
Метод Array.prototype.map создаёт новый массив, вызывая переданный колбэк для каждого элемента исходного массива. Однако он копирует только ссылки на объекты, а не сами объекты. Это означает:
- Если в колбэке вы возвращаете тот же объект (даже после мутации), новый массив будет содержать ссылки на те же объекты, что и исходный.
- Если вы возвращаете новый объект (например, через spread или
Object.assign), тогда в новом массиве будут новые объекты.
Механизм работы: map проходит по элементам, вызывает колбэк, и результат каждого вызова кладёт в новый массив. Для примитивов это копия значения, для объектов - копия ссылки. Мутация объекта внутри колбэка влияет на все массивы, которые содержат ссылку на этот объект.
На практике
Для senior-позиции важно понимать разницу между мутацией и иммутабельностью. Если вы добавляете свойство через obj.newProp = value внутри map, вы меняете исходные данные. Это часто приводит к багам, особенно при работе с состоянием в React или Redux.
Чтобы получить новый массив с новыми объектами, нужно явно создавать копию каждого объекта:
JAVASCRIPTconst newArray = oldArray.map(obj => ({ ...obj, newProp: value }));
Пример кода
JAVASCRIPTconst users = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }];// Мутация исходных объектовconst mutated = users.map(user => {user.age = 30;return user;});console.log(users[0].age); // 30 - исходный объект изменёнconsole.log(mutated[0] === users[0]); // true - та же ссылка// Создание новых объектовconst copied = users.map(user => ({ ...user, age: 30 }));console.log(users[0].age); // 30 (уже изменён выше)console.log(copied[0] === users[0]); // false - новый объект
Как отвечать на собеседовании
Начните с прямого ответа: "Новый массив, но старые объекты". Затем поясните, что map копирует ссылки, а не значения. Упомяните, что для создания новых объектов нужно использовать spread или Object.assign. Если спросят про производительность, отметьте, что глубокое копирование - дорогая операция, и её нужно избегать без необходимости.
Что проверяет интервьюер
Интервьюер проверяет понимание ссылочной семантики JavaScript, разницу между мутацией и иммутабельностью, а также умение предвидеть побочные эффекты. Это базовый вопрос, но на senior-уровне ожидается, что вы сразу назовёте проблему и предложите решение, а не просто констатируете факт.
Типичные ошибки
- Утверждение, что
mapсоздаёт глубокую копию объектов. - Игнорирование того, что мутация внутри колбэка влияет на исходный массив.
- Предложение использовать
mapдля иммутабельного обновления без явного копирования объектов. - Путаница между
mapиforEachв контексте мутаций.
> Похожие задачи по frontend
Какие бандлеры существуют и для чего они используются
Как положить результат промиса в массив по индексу в JavaScript?
Что такое генераторы в JavaScript и для чего они используются
Какие значения являются falsy в JavaScript
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью