源本科技 | 码上会

JavaScript 高阶函数 filter

2026/01/01
11
0

学习目标

  • 理解 filter() 的核心作用:按条件筛选元素

  • 掌握 filter() 的语法、参数与返回值行为

  • 能够在实际开发中用于数据过滤、权限控制、搜索匹配等场景

  • 区分 filter()map()find()some() 等方法的使用边界

  • 避免常见误区(如误以为会修改原数组、忽略布尔转换规则)


什么是 filter() 方法

filter() 是 ES5 引入的数组高阶方法,用于创建一个新数组,其中只包含通过回调函数测试的元素

核心特性:

  • 不修改原数组

  • 返回新数组(可能为空)

  • 跳过空槽(empty slots)

  • 依赖“真值”判断(falsy 值会被过滤掉)

function canVote(age) {
    return age >= 18;
}

const ages = [24, 33, 16, 40];
const voters = ages.filter(canVote);

console.log(voters); // [24, 33, 40]
console.log(ages);   // [24, 33, 16, 40] — 原数组未变

语法与参数

const newArray = arr.filter((element, index, array) => {
    // 返回 true 保留,false 过滤
}, thisArg);

参数

类型

说明

callback

Function

测试函数,必须返回布尔值(或可转为布尔的值)

element

任意

当前元素(必填)

index

number

当前索引(可选)

array

Array

原始数组(可选)

thisArg

任意

指定回调函数中的 this 值(可选)

示例:使用全部参数

const numbers = [10, -5, 0, 8, -2];

const positiveWithIndex = numbers.filter((num, idx, arr) => {
    console.log(`检查第 ${idx} 项: ${num} (总长: ${arr.length})`);
    return num > 0;
});

console.log(positiveWithIndex); // [10, 8]

典型应用场景

1. 数值过滤

// 正数筛选
const values = [112, 52, 0, -1, 944];
const positives = values.filter(x => x > 0);
console.log(positives); // [112, 52, 944]

// 偶数筛选
const nums = [11, 98, 31, 23, 944];
const evens = nums.filter(x => x % 2 === 0);
console.log(evens); // [98, 944]

2. 对象数组筛选

const users = [
    { name: "Alice", age: 25, active: true },
    { name: "Bob", age: 17, active: false },
    { name: "Charlie", age: 30, active: true }
];

// 筛选活跃用户
const activeUsers = users.filter(user => user.active);

// 筛选成年用户
const adults = users.filter(({ age }) => age >= 18);

console.log(activeUsers.length); // 2
console.log(adults.map(u => u.name)); // ["Alice", "Charlie"

3. 字符串搜索/过滤

const fruits = ["apple", "banana", "cherry", "apricot"];

// 包含 "ap" 的水果
const apFruits = fruits.filter(fruit => fruit.includes("ap"));
console.log(apFruits); // ["apple", "apricot"]

// 长度大于 5 的单词
const longWords = fruits.filter(word => word.length > 5);
console.log(longWords); // ["banana", "cherry", "apricot"]

4. 移除 falsy 值

常用技巧

const messy = [0, "", null, undefined, "hello", 42, false, true];

// 清理 falsy 值
const clean = messy.filter(Boolean);
console.log(clean); // ["hello", 42, true]

// 原理:Boolean(0) → false,Boolean("hello") → true

这是 JavaScript 中非常实用的“净化数组”技巧。


filter() vs 其他数组方法

方法

返回值

主要用途

是否修改原数组

filter()

新数组(符合条件的元素)

筛选

❌ 否

map()

新数组(每个元素转换结果)

转换

❌ 否

find()

单个元素(第一个匹配项)或 undefined

查找单个

❌ 否

some()

true / false

是否存在匹配

❌ 否

every()

true / false

是否全部匹配

❌ 否

使用场景对比

const scores = [85, 92, 78, 96];

// 我需要所有及格分数 → filter
scores.filter(s => s >= 60);

// 我只需要第一个优秀分数 → find
scores.find(s => s >= 90);

// 是否有人不及格? → some
scores.some(s => s < 60);

// 所有人都优秀吗? → every
scores.every(s => s >= 90);

高级技巧

1. 动态条件过滤

function createFilter(minAge, isActive) {
    return (user) => {
        if (minAge !== undefined && user.age < minAge) return false;
        if (isActive !== undefined && user.active !== isActive) return false;
        return true;
    };
}

const filtered = users.filter(createFilter(20, true));

2. 链式调用

与 map 结合

const products = [
    { name: "Laptop", price: 1200, category: "Electronics" },
    { name: "Book", price: 15, category: "Education" },
    { name: "Phone", price: 800, category: "Electronics" }
];

// 获取所有电子产品名称
const electronicNames = products
    .filter(p => p.category === "Electronics")
    .map(p => p.name);

console.log(electronicNames); // ["Laptop", "Phone"]

浏览器兼容性

filter() 自 ES5 起被广泛支持:

浏览器

最低版本

Chrome

1+

Edge

12+

Firefox

1+

Safari

3+

Opera

10.1+

所有现代浏览器均完全支持,无需 polyfill。


重点总结

要点

说明

不可变性

filter() 返回新数组,原数组不变

真值判断

回调返回 truthy 则保留,falsy 则过滤

空数组安全

若无匹配项,返回空数组 [](非 null

跳过空槽

[1, , 3].filter(x => x)[1, 3]

适用场景

数据筛选、权限过滤、搜索、清理 falsy 值

性能

时间复杂度 O(n),适合中等规模数据


思考题

  1. 以下代码输出什么?为什么?

    const arr = [1, 2, 3, 4];
    const result = arr.filter(x => {
        console.log(x);
        return x > 2;
    });
    console.log(result);
    
  2. 如何使用 filter() 实现“从用户列表中排除已删除(deleted: true)的用户”?