标准答案
- map 返回一个新数组,不应该修改原数组。
- callback 接收当前值、索引和原数组。
- 需要支持 thisArg,让回调里的 this 指向指定对象。
- 稀疏数组里不存在的索引不会执行 callback。
- 实现前要检查调用者不是 null 或 undefined,callback 必须是函数。
题目解析
手写 map 不是简单 for 循环 push。更接近原生行为的实现要考虑 thisArg、稀疏数组和基础参数校验。
结果数组的长度应该和原数组一致。对于稀疏数组,空位仍然是空位,不应该因为 push 变成连续数组。
这道题适合体现对数组迭代方法共同模式的理解:不改变原数组,按索引访问,回调参数一致,返回新集合。
代码示例
下面的实现保留数组长度,并跳过不存在的索引。
JavaScript
function map(array, callback, thisArg) {
if (array == null) {
throw new TypeError('array is null or undefined')
}
if (typeof callback !== 'function') {
throw new TypeError('callback must be a function')
}
const source = Object(array)
const length = source.length >>> 0
const result = new Array(length)
for (let index = 0; index < length; index += 1) {
if (index in source) {
result[index] = callback.call(thisArg, source[index], index, source)
}
}
return result
}常见误区
- 用 push 生成结果,导致稀疏数组空位行为和原生 map 不一致。
- 忘记传 index 和原数组,回调能力不完整。
- 忽略 thisArg,包装对象方法时上下文不符合预期。