魯斯前端布魯斯前端

文章中英模式

布魯斯前端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執行副作用undefinedarr.forEach(console.log)
reduce將陣列歸納為單一值累加的結果arr.reduce((a, b) => a + b)