You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

for循环、.map()与.filter()何时性能更优?

基于对象属性值查找对象:循环与数组方法的性能对比

最近针对「如何根据对象的某个属性值从对象数组中查找目标对象」这个问题,我写了一套测试脚本,用来对比不同实现方式的性能和扩展性,先给大家看看测试代码:

const elementsInObject = 1000000;
const lengthOfItems = 5; // 生成随机文本的长度

// 生成随机字符串的工具函数
function randomText() {
  var text = "";
  var possible = "abcdefghijklmnopqrstuvwxyz";
  for (var i = 0; i < lengthOfItems; i++)
    text += possible.charAt(Math.floor(Math.random() * possible.length));
  return text;
}

// 创建测试用的对象数组
console.time("creatingObject");
var arrObj = [];
for (let i = 0; i < elementsInObject; i++) {
  let el = {
    prop1: randomText(),
    prop2: randomText(),
    types: [randomText(), randomText()]
  };
  arrObj.push(el);
}
console.timeEnd("creatingObject");

// 嵌套for循环实现
console.time("forFor");
var result = [];
for (let i = 0; i < arrObj.length; i++) {
  for(let q=0; q<arrObj[i].types.length; q++){
    if (arrObj[i].types[q] == "abcde") {
      result.push(arrObj[i]);
    }
  }
}
console.timeEnd("forFor");

// for循环+includes实现
console.time("forIncludes");
var result = [];
for (let i = 0; i < arrObj.length; i++) {
  if (arrObj[i].types.includes("abcde")) {
    result.push(arrObj[i]);
  }
}
console.timeEnd("forIncludes");

// filter+includes实现
console.time("filterIncludes");
var result = arrObj.filter(obj => {
  return obj.types.includes("abcde");
});
console.timeEnd("filterIncludes");

// map+手动收集结果(不推荐的用法)
console.time("mapIncludes");
var result = [];
arrObj.map(obj => {
  if (obj.types.includes("abcde")) {
    result.push(obj);
  }
});
console.timeEnd("mapIncludes");

// filter+indexOf实现
console.time("filterIndexOf");
var result = arrObj.filter(obj => {
  return obj.types.indexOf("abcde") > -1;
});
console.timeEnd("filterIndexOf");

测试结果

在Node.js和Chrome浏览器环境中,嵌套for循环是性能表现最好的实现方式;不过在Firefox里,不同方法的性能差异会有所不同。

核心疑问:filter()或map()何时性能优于for循环?

先明确一点:map()从来都不应该用来做筛选操作——它的设计初衷是转换数组中的每个元素,返回一个新数组,用map来手动收集符合条件的元素属于语义误用,性能自然也不会理想,日常开发里千万别这么写。

至于filter(),它在这些场景下的价值会超过普通for循环:

  • 可读性优先的场景:filter()的语义非常清晰,一眼就能看出这段代码是在做「筛选符合条件的元素」操作,代码更简洁,团队协作时更容易理解和维护。如果你的项目更看重代码的可维护性,处理的数据量又不是百万级别的超大数组,filter()是更好的选择。
  • 现代引擎优化加持的场景:部分现代JS引擎会对高阶函数做专门的JIT编译优化,当数组元素是简单类型(比如字符串、数字),或者筛选逻辑比较简单时,filter()的性能可能会接近甚至偶尔超过普通for循环。
  • 需要链式调用的场景:如果筛选后还要做转换、聚合等操作,filter()可以和map()、reduce()等数组方法无缝链式调用,写出更流畅的函数式代码。比如arr.filter(...).map(...).reduce(...)这种写法,比嵌套多层for循环要简洁得多,代码的可维护性提升明显。

最后要提醒的是:性能测试一定要结合实际业务场景。如果是处理百万级别的复杂对象数组,普通for循环的性能优势确实很明显;但日常开发中大部分场景都是处理几千条以内的数据,这时候filter()和for循环的性能差异几乎可以忽略不计,优先选择更易读的代码才是明智之举。

内容的提问来源于stack exchange,提问作者Emeeus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:13:05