Интервью-вопрос
Что делает метод map в JavaScript
map используют, когда нужно преобразовать массив в новый массив результатов. В ответе важно не спутать его с forEach, не забыть return, учесть async callback и не мутировать объекты случайно.
- Добавлен
- Редакция
Подготовьте короткий ответ и пару деталей на случай уточняющих вопросов.
Мини-квиз
Проверка перед разбором
Несколько быстрых вопросов перед разбором. Так проще поймать места, которые только кажутся понятными.
Вопрос 1 из 50 правильно
Разбор
Разобраться, а не зазубрить
Дальше разбираем суть, типичные уточнения и места, где легко сказать лишнее или перепутать термины.
Базовая идея
Array.prototype.map нужен для трансформации массива. Вы передаете функцию. JavaScript вызывает ее для каждого существующего элемента и кладет возвращенное значение в новый массив на ту же позицию.
На интервью можно ответить так:
map проходит по массиву, применяет callback к каждому существующему элементу и возвращает новый массив результатов. Исходный массив он сам не меняет. Я использую его, когда хочу из одних данных получить другие, например подготовить список для рендера.
Так лучше, чем сказать только "перебирает массив". Перебирают массив многие методы. Смысл map именно в новом массиве результата.
Как это выглядит в коде
Типичный пример для фронтенда выглядит так. С сервера пришли пользователи, а для UI нужен список подписей.
const users = [
{ id: 1, name: "Ana" },
{ id: 2, name: "Max" },
];
const labels = users.map((user, index) => `${index + 1}. ${user.name}`);
// labels: ["1. Ana", "2. Max"]Callback получает три аргумента: текущий элемент, индекс и сам массив. Чаще всего вам достаточно первого аргумента. Индекс полезен для подписи или вычисления позиции. Но в React не стоит автоматически делать его ключом для динамического списка. При вставках и удалениях можно получить неверное сопоставление DOM и данных.
Как выбрать метод
На интервью полезно показать, что вы выбираете метод по задаче, а не используете map везде. Если нужен массив такой же длины с новыми значениями, map подходит. Если вы только делаете побочный эффект, фильтруете или ищете один элемент, лучше взять другой инструмент.
Когда map уместен
Используйте map.Выберите forEach или обычный цикл.Используйте filter, а не возвращайте undefined из map.Используйте for...of, some, every или find по задаче.Главная ловушка: map не делает данные иммутабельными сам по себе
map не меняет исходный массив как структуру. Но callback может менять объекты внутри массива. Это важно для React и любого кода, где вы рассчитываете на предсказуемые данные.
Плохой вариант:
const nextUsers = users.map((user) => {
if (user.id === 1) {
user.name = "Anna";
}
return user;
});Здесь создается новый массив. Но объект user остается той же ссылкой и меняется на месте. Безопаснее вернуть новый объект только для измененного элемента.
const nextUsers = users.map((user) =>
user.id === 1 ? { ...user, name: "Anna" } : user
);Так вы показываете практический вывод. map помогает создать новый массив, но за иммутабельность вложенных данных отвечаете вы.
Async callback и Promise.all
Если callback объявлен как async, он всегда возвращает промис. map не будет ждать каждый промис. Он просто соберет их в новый массив.
const promises = ids.map(async (id) => {
const response = await fetch(`/api/users/${id}`);
return response.json();
});
const users = await Promise.all(promises);Это нормальный вариант для параллельных запросов, если их количество контролируемое и вы готовы обработать ошибку. Не кладите promises в состояние как готовые данные. Сначала дождитесь результата, покажите loading, обработайте error. Еще важно не обновлять состояние после размонтирования компонента.
Если список id меняется быстро, старый запрос может прийти позже нового и перезаписать UI устаревшими данными. В компоненте обычно добавляют отмену через AbortController или проверку актуальности запроса в cleanup. Если запросов много или важен порядок выполнения с паузами, не запускайте все бездумно через Promise.all. Тогда лучше использовать цикл, очередь или ограничитель параллельности.
Разреженные массивы
У map есть нюанс с пустыми слотами массива. Для такого слота callback не вызывается. В результате тоже остается пустой слот.
const result = [1, , 3].map((value) => value * 2);
// result выглядит как [2, empty, 6]
// callback был вызван только для 1 и 3Это отличается от элемента со значением undefined. В реальном frontend-коде лучше не строить логику на holes. Если данные могут быть разреженными, нормализуйте их перед рендером или явно фильтруйте значения.
Практический вывод
Хороший ответ на этот вопрос короткий, но с границами применения. Скажите, что map возвращает новый массив результатов, сохраняет порядок и длину для существующих позиций, не мутирует исходный массив как структуру и подходит для чистой трансформации.
Затем добавьте один практический нюанс. Например: "В React я часто использую map для рендера списка или иммутабельного обновления массива, но слежу, чтобы не мутировать объекты внутри callback". Такая формулировка звучит сильнее, чем сухое определение.
Частые ошибки
Где обычно ошибаются
Проверьте формулировки, которые звучат уверенно, но на интервью быстро выдают пробелы.
- 1
Ждать изменения исходного массива
mapвозвращает новый массив, поэтому вызов без присваивания часто ничего полезного не дает. Если вам нужен результат, сохраните его в переменную или верните из функции. Если нужно изменить состояние в React, создайте новый массив и передайте его в setter. - 2
Использовать map ради side effects
Когда результатmapигнорируется, код выглядит так, будто вы хотели преобразование, но на деле делаете побочные эффекты. Это сбивает читающего и может создать лишний массив. Для логирования, пуша в другую структуру или вызова внешнего API обычно лучшеforEachили цикл. - 3
Забыть return в callback
В стрелочной функции с фигурными скобками нужен явныйreturn. Иначе вы получите массивundefined, а UI может отрендерить пустые элементы или сломать дальнейшие вычисления. - 4
Путать map и filter
mapне удаляет элементы, он преобразует каждый существующий элемент. Если возвращатьnullилиundefinedдля ненужных значений, длина массива сохранится. Для отбора используйтеfilter, затем при необходимостиmap. - 5
Не учесть async результат
array.map(async item => ...)возвращает массив промисов. Если сразу положить его в состояние как данные, UI получит промисы вместо значений и может показать пустой список или[object Promise]. Для параллельной загрузки дождитесьPromise.all, обработайтеloadingиerror, а для лимита запросов используйте отдельный контроль параллельности.
Follow-up
Что могут спросить дальше
Короткие ответы на вопросы, которыми проверяют понимание map, callback и практических ловушек в JavaScript.
Живые ответы
Видео с похожим вопросом
Если найдем публичные интервью с таким вопросом, добавим их сюда. Их удобно смотреть после теории, чтобы свериться с живыми ответами.
Пока видео нет. Когда появятся подходящие публичные интервью, добавим их в этот блок, чтобы можно было сравнить разбор с тем, как отвечают реальные кандидаты.
Что ответить про метод previews в JavaScript 😎
В стандартном JavaScript метода previews нет. Здесь разбираем, как спокойно ответить на такой вопрос, уточнить контекст и не спутать его с preventDefault().
Что такое замыкание
Разбор вопроса «Что такое замыкание» для Frontend Developer: что проверяет интервьюер, ключевые тезисы, практические примеры и частые ошибки.