魯斯前端布魯斯前端

文章中英模式

布魯斯前端JS面試題目 - 實作陣列 filter 方法

學習如何手動實作 JavaScript 的 Array.filter() 方法,理解高階函數、回調函數與陣列處理機制。

影片縮圖

懶得看文章?那就來看影片吧

Array.filter() 方法概述

Array.filter() 是 JavaScript 中常用的陣列方法,用於創建一個新陣列,其中包含所有通過特定條件測試的元素。這個方法不會改變原陣列,而是返回一個新的陣列。

原生 filter 方法使用方式

// 基本語法
array.filter(callback(element[, index[, array]])[, thisArg])

// 使用範例
const numbers = [1, 2, 3, 4, 5, 6];
const evenNumbers = numbers.filter(num => num % 2 === 0);
console.log(evenNumbers); // [2, 4, 6]

參數說明

  • 1. callback:用於測試陣列每個元素的函數,返回 true 表示保留該元素
  • 2. element:當前正在處理的元素
  • 3. index(可選):當前元素的索引
  • 4. array(可選):調用 filter 的陣列本身
  • 5. thisArg(可選):執行 callback 時用作 this 的值

實作 Array.filter() 方法

在面試中,實作 Array.filter() 可以測試對高階函數、回調函數和 this 綁定的理解。以下是實作步驟:

基本實作

// 基本實作
Array.prototype.myFilter = 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) {
      // 呼叫回調函數測試條件,如果返回 true 則保留該元素
      if (callback(this[i], i, this)) {
        result.push(this[i]);
      }
    }
  }
  
  return result;
};

// 使用範例
const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.myFilter(num => num % 2 === 0);
console.log(evenNumbers); // [2, 4]

實際應用範例

以下是自定義 filter 方法的幾個實際應用:

1. 過濾物件陣列

const users = [
  { id: 1, name: 'Alice', age: 25, active: true },
  { id: 2, name: 'Bob', age: 17, active: false },
  { id: 3, name: 'Charlie', age: 30, active: true },
  { id: 4, name: 'David', age: 15, active: true },
  { id: 5, name: 'Eve', age: 28, active: false }
];

// 過濾出活躍的成年用戶
const activeAdults = users.myFilter(user => user.active && user.age >= 18);
console.log(activeAdults);
// [
//   { id: 1, name: 'Alice', age: 25, active: true },
//   { id: 3, name: 'Charlie', age: 30, active: true }
// ]

2. 過濾無效值

const values = [0, null, undefined, '', false, NaN, 'hello', 42];

// 過濾出真值
const truthyValues = values.myFilter(Boolean);
console.log(truthyValues); // ['hello', 42]

3. 複合條件過濾

const products = [
  { id: 1, name: 'Laptop', price: 1200, inStock: true, category: 'electronics' },
  { id: 2, name: 'Book', price: 20, inStock: true, category: 'books' },
  { id: 3, name: 'Phone', price: 800, inStock: false, category: 'electronics' },
  { id: 4, name: 'Monitor', price: 300, inStock: true, category: 'electronics' },
  { id: 5, name: 'Desk', price: 150, inStock: true, category: 'furniture' }
];

// 过滤条件:电子产品、库存有、价格小于 1000
const availableElectronics = products.myFilter(product => 
  product.category === 'electronics' && 
  product.inStock && 
  product.price < 1000
);

console.log(availableElectronics);
// [
//   { id: 4, name: 'Monitor', price: 300, inStock: true, category: 'electronics' }
// ]