在JavaScript的实际开发中,我们经常会遇到需要从一个对象数组中筛选出符合特定键条件的元素的需求,比如从用户列表中筛选出年龄大于18岁的用户,或者从商品列表中筛选出库存大于0的商品。这类需求如果处理不当,很容易写出冗余且低效的代码,下面介绍几种高效的实现方式。

使用filter方法结合条件判断
数组的filter方法是处理这类需求最基础也最常用的方式,它会遍历数组的每一个元素,将符合条件的元素返回组成新的数组,不会改变原数组。我们可以根据对象键的取值来设置筛选条件。
比如我们有一个用户数组,需要筛选出年龄大于等于18岁的用户:
// 用户数组
const userList = [
{ id: 1, name: '张三', age: 16 },
{ id: 2, name: '李四', age: 20 },
{ id: 3, name: '王五', age: 19 },
{ id: 4, name: '赵六', age: 15 }
];
// 根据age键过滤出成年用户
const adultUsers = userList.filter(item => {
// 判断当前对象的age键是否存在且符合条件
return item.hasOwnProperty('age') && item.age >= 18;
});
console.log(adultUsers);
// 输出: [{ id: 2, name: '李四', age: 20 }, { id: 3, name: '王五', age: 19 }]
根据多个对象键组合过滤
实际场景中往往需要同时根据多个键的条件来筛选元素,这时候只需要在filter的回调函数中添加多个判断条件即可,多个条件之间可以用逻辑与&&或者逻辑或||连接。
比如我们需要筛选出年龄大于等于18岁且名字长度大于1的用户:
const adultLongNameUsers = userList.filter(item => {
return item.hasOwnProperty('age') &&
item.age >= 18 &&
item.hasOwnProperty('name') &&
item.name.length > 1;
});
console.log(adultLongNameUsers);
// 输出: [{ id: 2, name: '李四', age: 20 }, { id: 3, name: '王五', age: 19 }]
使用Map优化高频过滤场景
如果我们需要多次根据同一个键的不同取值来过滤同一个数组,反复调用filter方法会重复遍历数组,效率较低。这时候可以先将数组转换为以目标键为键的Map结构,后续过滤时直接从Map中取值即可,减少遍历次数。
比如我们有一个商品数组,需要多次根据分类键category筛选不同分类的商品:
const productList = [
{ id: 1, name: '手机', category: '数码', price: 2999 },
{ id: 2, name: '笔记本', category: '数码', price: 5999 },
{ id: 3, name: 'T恤', category: '服饰', price: 99 },
{ id: 4, name: '牛仔裤', category: '服饰', price: 199 }
];
// 构建以category为键的Map,值为对应分类的商品数组
const productMap = new Map();
productList.forEach(item => {
const category = item.category;
if (productMap.has(category)) {
productMap.get(category).push(item);
} else {
productMap.set(category, [item]);
}
});
// 后续需要筛选数码类商品时直接取值
const digitalProducts = productMap.get('数码') || [];
console.log(digitalProducts);
// 输出: [{ id: 1, name: '手机', category: '数码', price: 2999 }, { id: 2, name: '笔记本', category: '数码', price: 5999 }]
不同实现方式的性能对比
我们可以通过简单的测试来对比不同方式的性能,以下是三种常见场景的对比结果:
| 实现方式 | 单次过滤耗时(10000条数据) | 适用场景 |
|---|---|---|
| for循环遍历 | 约0.3ms | 需要兼容极低版本环境,或需要中途跳出循环的场景 |
| filter方法 | 约0.5ms | 单次过滤,代码简洁性要求高的场景 |
| Map预构建后取值 | 预构建约1.2ms,后续取值约0.01ms | 多次重复过滤同一个数组的场景 |
注意事项
- 使用
filter方法时,建议先判断目标键是否存在,避免出现undefined相关的报错。 - 如果原数组会被修改,预构建的
Map需要同步更新,否则会出现数据不一致的问题。 - 当数组长度较小时,不同实现方式的性能差异可以忽略,优先选择代码可读性更高的方式即可。
在实际开发中,不需要过度追求极致的性能优化,优先保证代码的清晰和可维护性,只有在遇到性能瓶颈时再针对性选择更高效的实现方式。
JavaScript数组过滤对象键filter方法高效技巧修改时间:2026-07-19 19:21:29