文章中英模式
布鲁斯前端JS面试题目 - 实现数组 map 方法
学习如何手动实现 JavaScript 的 Array.map() 方法,掌握高阶函数与迭代器模式,提升前端面试竞争力。
文章中英模式
懒得看文章?那就来看视频吧
Array.map() 方法概述
Array.map()
是 JavaScript 中常用的数组方法,能够将数组中的每个元素经过函数转换后,返回一个全新的数组。这种一对一的转换模式让数据处理变得简洁优雅。
原生 map 方法使用方式
// 基本语法
array.map(callback(currentValue[, index[, array]])[, thisArg])
// 使用示例
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
参数说明
- 1. callback:为每个元素执行的函数,接收 1-3 个参数
- 2. currentValue:当前正在处理的元素
- 3. index(可选):当前元素的索引
- 4. array(可选):调用 map 的数组本身
- 5. thisArg(可选):执行 callback 时用作 this 的值
实现 Array.map() 方法
在面试中,实现 Array.map()
是测试对高阶函数和 JavaScript 面向对象程序设计理解的好题目。以下是基本实现步骤:
基本实现
// 基本实现 map 方法
Array.prototype.myMap = function(callback) {
// 检查 callback 是否为函数
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
const result = [];
const length = this.length;
// 遍历数组
for (let i = 0; i < length; i++) {
// 只处理存在的元素(处理稀疏数组)
if (i in this) {
// 调用回调函数,将结果存入新数组
result[i] = callback(this[i], i, this);
}
}
return result;
};
// 使用示例
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.myMap(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
实际应用示例
以下是一些 map
方法的实际应用场景:
1. 格式化数据
// 从API获取的原始用户数据
const users = [
{ id: 1, first_name: 'John', last_name: 'Doe', age: 28 },
{ id: 2, first_name: 'Jane', last_name: 'Smith', age: 32 },
{ id: 3, first_name: 'Bob', last_name: 'Johnson', age: 45 }
];
// 格式化数据以在UI中显示
const formattedUsers = users.myMap(user => ({
id: user.id,
fullName: `${user.first_name} ${user.last_name}`,
ageGroup: user.age < 30 ? 'young' : 'adult'
}));
console.log(formattedUsers);
/*
[
{ id: 1, fullName: 'John Doe', ageGroup: 'young' },
{ id: 2, fullName: 'Jane Smith', ageGroup: 'adult' },
{ id: 3, fullName: 'Bob Johnson', ageGroup: 'adult' }
]
*/
2. 创建 DOM 元素数组
// React 组件中的示例
function TodoList({ todos }) {
return (
<ul>
{todos.map(todo => (
<li key={todo.id}>
<input type="checkbox" checked={todo.completed} />
<span>{todo.text}</span>
</li>
))}
</ul>
);
}
3. 数学计算与数组转换
// 计算半径数组对应的面积
const radii = [2, 5, 7.5, 10];
const areas = radii.myMap(radius => Math.PI * radius * radius);
console.log(areas);
// [12.57, 78.54, 176.71, 314.16] (四舍五入值)
// 将摄氏温度转换为华氏温度
const celsius = [0, 15, 25, 30, 100];
const fahrenheit = celsius.myMap(temp => (temp * 9/5) + 32);
console.log(fahrenheit);
// [32, 59, 77, 86, 212]
map 与其他数组方法比较
map
方法与其他数组方法在功能上有一些区别和重叠:
方法 | 功能 | 返回值 | 示例 |
---|---|---|---|
map | 转换每个元素 | 新数组,长度相同 | arr.map(x => x * 2) |
filter | 过滤符合条件的元素 | 新数组,长度可能减少 | arr.filter(x => x > 5) |
forEach | 执行副作用 | undefined | arr.forEach(console.log) |
reduce | 将数组归纳为单一值 | 累积的结果 | arr.reduce((a, b) => a + b) |