Как работает callback в методе map в JavaScript и что означают его аргументы
Что проверяют
Знаете ли вы сигнатуру колбэка наизусть и понимаете ли, что map строит новый массив из возвращаемых значений. Вопрос базовый, на нём отсеивают тех, кто использует map вместо forEach и забывает третий аргумент.
Как отвечать
- Сигнатура:
arr.map(callback, thisArg). Колбэк получает три аргумента: текущий элемент, его индекс и сам массив, на котором вызван метод. - Возврат колбэка становится элементом нового массива. Длина результата равна длине исходного, сам исходный массив
mapне меняет, хотя колбэк может мутировать его элементы. - Забыли
returnв теле со скобками, получите массив изundefined. У стрелочной функции без скобок возврат неявный. thisArgзадаётthisвнутри колбэка, но на стрелочные функции не действует: у нихthisлексический.- Диапазон обхода фиксируется до первого вызова: добавленные по ходу элементы не посещаются, изменённые читаются новыми значениями.
- В разреженном массиве дырки пропускаются: колбэк для них не вызывается, в результате они остаются дырками.
- Асинхронный колбэк возвращает промис, поэтому
map(async ...)даёт массив промисов, дальше нуженawait Promise.all(...).
const users = [{ id: 7 }, { id: 9 }];
const rows = users.map((u, i, all) => `${i + 1}/${all.length}: ${u.id}`);
// ['1/2: 7', '2/2: 9']
console.log(["1", "2", "3"].map(Number)); // [1, 2, 3]
console.log(["1", "2", "3"].map(parseInt)); // [1, NaN, NaN]Где спотыкаются
Называют два аргумента и забывают массив. Он нужен, когда колбэк вынесен в отдельную функцию и ему требуется соседний элемент или длина.
Передают функцию с необязательными параметрами: map(parseInt) ловит индекс как основание системы счисления. Правило простое: в map отдают функции ровно одного аргумента, иначе оборачивают стрелкой.
Используют map ради побочного эффекта и выбрасывают результат. Это лишний массив и ложный сигнал читателю, для эффектов есть forEach и for..of.
Ждут последовательного выполнения от асинхронного колбэка. map запускает все вызовы сразу, последовательность делается циклом с await.