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

JS中indexOf、includes底层实现及性能测试负数值问题咨询

indexOf与includes相关问题解答

1 底层运行逻辑

  • 按照ECMAScript标准定义,Array.prototype.indexOf和Array.prototype.includes的默认实现都是线性遍历数组来匹配目标元素,通用场景下没有特殊的哈希索引或者预存结构优化,会遍历到匹配元素或者数组末尾才结束,仅部分JS引擎会针对极特殊场景做自定义优化。
  • 二者核心差异是比较规则:indexOf使用严格相等(===)做匹配,无法识别NaN;includes使用SameValueZero规则做匹配,可以正确匹配NaN,对空字符串、数组空槽位的匹配逻辑也和indexOf有细微区别。
  • 你测试场景中includes更快是因为Google Apps Script基于V8引擎运行,V8对includes的短字符串匹配(尤其是空字符串这类高频目标)做了专门的快速路径优化,匹配开销比indexOf的严格相等路径更低。

2 时间差为负数的原因

该问题核心是计时方法错误:

  • new Date().getMilliseconds()仅返回当前时间的毫秒部分(取值范围0-999),不是完整的时间戳。如果测试过程中跨越了秒级边界,比如开始计时时毫秒位是990,结束时是下一秒的15毫秒,计算得到的差值就是15 - 990 = -975,这就是负数的直接来源。
  • 次要影响因素是JS单线程执行的调度逻辑:测试过程中如果触发了引擎垃圾回收、系统后台任务抢占时间片,也会导致计时结果出现偏差,但不会稳定出现负数。
  • 修正方法:将getMilliseconds()替换为getTime()获取完整的毫秒级时间戳,或者使用环境支持的performance.now()做高精度计时,同时建议给所有局部变量加上声明,避免全局变量挂载带来的额外开销。

修正后测试代码示例:

function myFunction() {
  const array = [1, 2, 3, "", 5];
  const t0 = new Date().getTime();
  let j = 0;
  while(j < 10000000) {
    const x = array.indexOf("") > -1;
    j++;
  }
  const t1 = new Date().getTime();
  console.log(`Call to indexOf took ${t1 - t0} milliseconds.`);

  let i = 0;
  const t2 = new Date().getTime();
  while(i < 10000000) {
    const y = array.includes("");
    i++;
  }
  const t3 = new Date().getTime();
  console.log(`Call to includes took ${t3 - t2} milliseconds.`);
}

3 学习资源搜索建议

可使用以下关键词搜索获取相关资料:

  • ECMA-262 规范 Array.prototype.indexOf / includes 定义
  • V8 引擎 Array 方法实现源码
  • JS 数组方法性能对比测试

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 17:54:08