理解 JavaScript 数组的 map() 方法:简单指南

`map()` 方法通过将提供的函数(`callbackFn`)应用于原始数组的每个元素来创建一个**新数组**。它非常适合在不修改原始数组的情况下转换数据。

句法

array.map(callbackFn, thisArg)
  • callbackFn:在每个数组元素上运行的函数,具有以下参数:element:当前元素。index:当前索引。array:正在遍历的数组。
  • thisArg(可选):在回调函数中用作 this 的值。
  • 主要特点

  • 返回一个新数组:原始数组保持不变。
  • 跳过空槽:对于稀疏数组中未分配的元素,不会调用回调。
  • 通用用法:与类似数组的对象(例如,NodeLists)一起使用。
  • 示例

    1. 基本示例:变换数字

    const numbers = [1, 4, 9];
    const roots = numbers.map((num) => Math.sqrt(num));
    console.log(roots); // [1, 2, 3]

    2. 重新格式化对象

    const kvArray = [
      { key: 1, value: 10 },
      { key: 2, value: 20 },
    ];
    const reformatted = kvArray.map(({ key, value }) => ({ [key]: value }));
    console.log(reformatted); // [{ 1: 10 }, { 2: 20 }]

    3. 使用 parseInt 和 map

    // Common mistake:
    console.log(["1", "2", "3"].map(parseInt)); // [1, NaN, NaN]
    
    // Correct approach:
    console.log(["1", "2", "3"].map((str) => parseInt(str, 10))); // [1, 2, 3]
    
    // Alternative:
    console.log(["1", "2", "3"].map(Number)); // [1, 2, 3]

    4.避免未定义的结果

    回调不返回任何内容会导致新数组中出现“未定义”:

    const numbers = [1, 2, 3, 4];
    const result = numbers.map((num, index) => (index < 3 ? num : undefined));
    console.log(result); // [1, 2, 3, undefined]

    使用 `filter()` 或 `flatMap()` 来删除不需要的元素。

    5. 副作用(反模式)

    避免使用 `map()` 进行有副作用的操作,例如更新变量:

    const cart = [5, 15, 25];
    let total = 0;
    
    // Avoid this:
    const withTax = cart.map((cost) => {
      total += cost;
      return cost * 1.2;
    });
    
    // Instead, use separate methods:
    const total = cart.reduce((sum, cost) => sum + cost, 0);
    const withTax = cart.map((cost) => cost * 1.2);

    6.访问其他数组元素

    第三个参数(“数组”)允许在转换期间访问邻居:

    const numbers = [3, -1, 1, 4];
    const averaged = numbers.map((num, idx, arr) => {
      const prev = arr[idx - 1] || 0;
      const next = arr[idx + 1] || 0;
      return (prev + num + next) / 3;
    });
    console.log(averaged);

    常见用例

  • 转换数据:对每个元素应用一个函数。
  • 重新格式化对象:改变数据的结构。
  • 映射 NodeLists:将 NodeList 等 DOM 元素转换为数组:
  • const elems = document.querySelectorAll("option:checked");
       const values = Array.from(elems).map(({ value }) => value);

    何时避免使用 map()

  • 不需要返回值:改用 forEach() 或 for...of。
  • 变异数据:创建新对象而不是改变原始对象:
  • const products = [{ name: "phone" }];
       const updated = products.map((p) => ({ ...p, price: 100 }));

    最后的建议

  • 仅纯函数:确保回调没有副作用。
  • 理解参数:知道 map() 将元素、索引和数组传递给回调。
  • 避免稀疏数组:空槽将保持空。
  • 使用`map()`来有效地简化你的数组转换代码!