在JavaScript中,有多种循环方法可以用来遍历数组或集合。不同的循环方法在性能上有所差异,了解这些差异有助于在实际开发中选择最适合的循环方法,正好今天无聊想测试一下看看到底是哪个循环方法性能最好。开造!!!!!

常见的JavaScript循环方法

  1. for 循环
  2. while 循环
  3. do-while 循环
  4. for-in 循环
  5. for-of 循环
  6. Array.prototype.forEach
  7. Array.prototype.map
  8. Array.prototype.filter
  9. Array.prototype.reduce
  10. Array.prototype.every
  11. Array.prototype.some

测试环境

计算机硬件

你知道JavaScript所有的循环方法中哪个性能最佳吗?_JavaScript

开发环境
浏览器:Google
前端环境:Vue2
Node版本: v16.20.2

测试代码

<script>
export default {
  data() {
    return {
      results: []
    }
  },
  mounted() {
    this.runTests();
  },
  methods: {
    runTests() {
      const array = Array.from({ length: 1000000 }, (_, i) => i); // 生成一个包含100万个元素的数组

      const testPerformance = (func, label) => {
        const start = performance.now(); // 记录开始时间
        for (let i = 0; i < 10; i++) {
          func(array); // 执行10次循环
        }
        const end = performance.now(); // 记录结束时间
        const averageTime = ((end - start) / 10).toFixed(2); // 计算平均执行时间
        console.log(`${label}: ${averageTime} ms`); // 打印执行时间
        this.results.push({ label, time: averageTime }); // 将结果添加到results数组中
      };

      // 1. for 循环
      testPerformance((arr) => {
        for (let i = 0; i < arr.length; i++) {
          arr[i]; // 访问数组元素
        }
      }, 'for 循环');

      // 2. while 循环
      testPerformance((arr) => {
        let i = 0;
        while (i < arr.length) {
          arr[i]; // 访问数组元素
          i++;
        }
      }, 'while 循环');

      // 3. do-while 循环
      testPerformance((arr) => {
        let i = 0;
        do {
          arr[i]; // 访问数组元素
          i++;
        } while (i < arr.length);
      }, 'do-while 循环');

      // 4. for-in 循环
      testPerformance((arr) => {
        for (const key in arr) {
          arr[key]; // 访问数组元素
        }
      }, 'for-in 循环');

      // 5. for-of 循环
      testPerformance((arr) => {
        for (const item of arr) {
          item; // 访问数组元素
        }
      }, 'for-of 循环');

      // 6. forEach 循环
      testPerformance((arr) => {
        arr.forEach(item => item); // 遍历数组元素
      }, 'forEach');

      // 7. map 函数
      testPerformance((arr) => {
        arr.map(item => item); // 遍历数组元素并返回新数组
      }, 'map 函数');

      // 8. filter 函数
      testPerformance((arr) => {
        arr.filter(item => true); // 遍历数组元素并过滤
      }, 'filter 函数');

      // 9. reduce 函数
      testPerformance((arr) => {
        arr.reduce((acc, item) => acc + item, 0); // 遍历数组元素并累加
      }, 'reduce 函数');

      // 10. every 函数
      testPerformance((arr) => {
        arr.every(item => true); // 遍历数组元素并检查是否满足条件
      }, 'every 函数');

      // 11. some 函数
      testPerformance((arr) => {
        arr.some(item => false); // 遍历数组元素并检查是否满足条件
      }, 'some 函数');
    }
  }
}
</script>

运行结果打印

你知道JavaScript所有的循环方法中哪个性能最佳吗?_数组元素_02

性能排行及原因

  1. for 循环
  • 性能最佳
  • 原因for 循环是最基本的循环结构,没有额外的函数调用开销,可以直接访问数组元素。
  • 串行
  1. while 循环
  • 性能较好
  • 原因while 循环同样没有额外的函数调用开销,但比 for 循环稍微复杂一点。
  • 串行
  1. do-while 循环
  • 性能较好
  • 原因do-while 循环与 while 循环类似,但先执行一次再判断条件。
  • 串行
  1. for-of 循环
  • 性能中等
  • 原因for-of 循环是ES6引入的新特性,内部使用迭代器,有一定的开销。
  • 串行
  1. forEach
  • 性能中等
  • 原因forEach 是数组方法,每次调用都会创建一个新的函数上下文。
  • 串行
  1. map
  • 性能较差
  • 原因map 不仅创建新的数组,还创建新的函数上下文。
  • 串行
  1. filter
  • 性能较差
  • 原因filter 创建新的数组,每次调用都会创建新的函数上下文。
  • 串行
  1. reduce
  • 性能较差
  • 原因reduce 创建新的函数上下文,且需要累加操作。
  • 串行
  1. every
  • 性能较差
  • 原因every 创建新的函数上下文,且可能提前终止。
  • 串行
  1. some
  • 性能较差
  • 原因some 创建新的函数上下文,且可能提前终止。
  • 串行

看到这里的大帅应该清楚以后写代码该怎么正确使用循环来提升性能了吧[狗头]