双等号 (==) 和三等号 (===) 之间的 JavaScript 性能差异

IT技术 javascript node.js performance browser comparison
2021-03-04 17:49:18

在 JavaScript 中,使用双等号 ( ==) 与使用三等号 ( )之间是否存在性能差异===

示例:if (foo == bar)vsif (foo === bar)

6个回答
  • 如果比较的类型相同,则它们是相同的也就是说它们使用完全相同的算法

  • 如果类型不同,则性能无关紧要。您要么需要类型强制,要么不需要。如果您不需要它,请不要使用,==因为您得到的结果可能出乎意料。

严格比较 ( ===) 总是会稍微快一点,但差异通常可以忽略不计

===如果您确定在比较中不需要类型强制,那么优先选择绝对是有意义的。它总是至少和 一样快==

好笑的是,因为=====对我来说,在这两个时间我跑测试中,FF7。我同意这===应该更快,但测试声称不然。(可能是 Javascript 引擎/CPU 负载的差异,谁知道呢)
2021-04-17 17:49:18
console.time("test") 2 === 2 console.timeEnd("test") VM137:3 test: 0.006103515625ms console.time("test1") 2 == 2 console.timeEnd("test1") VM147: 3 test1: 0.0048828125ms 我知道 === 稍微快一点我如何测试这个为什么我得到相反的结果是我的方法是错误的?
2021-04-18 17:49:18
@Nightfirecat:这很有趣。你是在比较变量还是文字?
2021-04-20 17:49:18
我只是使用它使用的默认测试 - 即“==/=== 仅限相同类型”测试,因为这些测试是其中最快的。我相信相同的模式出现在所有类型比较中,而不是常规比较测试中,不记得了。
2021-05-05 17:49:18
如果操作数的类型相同,则=====被指定为执行完全相同的步骤。
2021-05-15 17:49:18

编辑:供参考,这里是Axel Rauschmayer 博士的规范解释http://www.2ality.com/2011/06/javascript-equality.html 写得真好

=== (严格相等):只考虑相同类型的值相等。

  1. 未定义 === 未定义,空 === 空,
  2. NaN === 不包括自身,
  3. 原始 [Number|String|Boolean] === 原始值相等,
  4. 给自己(+0 === -0)
  5. 两个对象 [Array|Object|Function] === 只有自己(完全相同的实体)

== (宽大平等)

  1. 如果两个值具有相同的类型:与 === 进行比较。
  2. 未定义 == 空
  3. 数字和字符串:字符串 => 数字和比较
  4. 布尔值和非布尔值 => 非布尔值来编号和比较
  5. 字符串或数字 => 对象:将对象转换为原始对象并进行比较。

在所有现代 Javascript 环境中,它们的实现方式完全不同。简单来说,==通过将给定的变量转换为基元(字符串、数字、布尔值)测试相似性。===严格相同性测试,这意味着完全相同的对象或原始值无需转换。

如果你做 objOne == objTwo 实际发生的事情是 [[EQUALS]].call(objOne.valueOf(), objTwo.valueOf())

valueOf 的解析可能有点涉及,在 JS 中公开的函数和内部引擎的东西之间跳来跳去。可以说比较总是以两个强制为原始值的值结束,否则会抛出错误。

编辑: EQUALS实际上STRICT_EQUALS首先尝试抢占过程的其余部分。

这里有趣的一点是 valueOf(及其伙伴 toString)是可覆盖的。在 Chrome 中运行这段代码(我认为任何 webkit,不确定 JSC 和 V8 是否共享此花絮)。它会让你大吃一惊:

var actions = [];
var overload = {
  valueOf: function(){
    var caller = arguments.callee.caller;
    actions.push({
      operation: caller.name,
      left: caller.arguments[0] === this ? "unknown" : this,
      right: caller.arguments[0]
    });
    return Object.prototype.toString.call(this);
  }
};
overload.toString = overload.valueOf;
overload == 10;
overload === 10;
overload * 10;
10 / overload;
overload in window;
-overload;
+overload;
overload < 5;
overload > 5;
[][overload];
overload == overload;
console.log(actions);

输出:

[ { operation: 'EQUALS',
    left: overload,
    right: 10 },
  { operation: 'MUL',
    left: overload,
    right: 10 },
  { operation: 'DIV',
    left: 'unknown',
    right: overload },
  { operation: 'IN',
    left: overload,
    right: DOMWindow },
  { operation: 'UNARY_MINUS',
    left: overload,
    right: undefined },
  { operation: 'TO_NUMBER',
    left: overload,
    right: undefined },
  { operation: 'COMPARE',
    left: overload,
    right: 5 },
  { operation: 'COMPARE',
    left: 'unknown',
    right: overload },
  { operation: 'ToString',
    left: 'unknown',
    right: overload } ]

==之间差异的本质===通过===未出现在该列表中来说明。它完全跳过了进入 JavascriptLand 的过程。在比较性能时,这种冒险是昂贵的。

但是,您需要考虑引擎优化。对于大多数对象,引擎将能够省去大部分步骤并留在 NativeLand 中并获得几乎相同的性能。但这并不能保证,如果某些因素阻止引擎使用优化、代码中的某些花哨或覆盖内置函数或无数问题,那么您会立即看到性能方面的结果。===强迫它。

=== 几乎是 Javascript 中唯一不可变的东西。

....你有没有在第一句话后阅读我的帖子?我确实包含了 V8 输出。简短回答: == 首先调用 === 并且在 === 为真的情况下,差异可以忽略不计。除此之外,== 根据定义必须输掉。
2021-04-21 17:49:18
只是为了后代注意。我的上述证据是我想出的一种新颖方法,它能够从任意 JavaScript 对象中识别内部 JS 引擎操作符函数调用者和正确定位的操作数,在所有当前使用 V8 或 JavaScriptCore 的实现中,我从未在其他地方看到过,并且它直接启用了 JS 中的运算符重载,否则这是不可能的,目前还没有成功实现。
2021-04-24 17:49:18
这真的应该是答案,imo。== 调用 === 然后尝试强制转换以查看它是否以其他方式相同。对于不相等的对象,当您尝试比较身份时,=== 显然更快。
2021-04-25 17:49:18
我读了它。抱歉,我应该更具体地说明缺少的证据:关于“所有现代 Javascript 环境”的部分。公开的 V8 内部结构很有趣,但valueOf()自 1997 年的 ECMAScript 1 以来就已经存在,因此并不新颖。你还没有解决我的观点,即当两个操作数是相同类型时会发生什么的问题。operator == {}添加operator === {}到您的示例中,您会看到它们都没有出现在您的actions数组中。
2021-05-05 17:49:18
你的证据在哪里?由于=====被指定为在操作数为相同类型时完全相同的工作,我无法相信在这种情况下 JS 环境会以不同的方式实现它们。
2021-05-12 17:49:18

由于性能,我认为===具有更好的性能,因为===比 更严格==

例如,在 Chrome 控制台中尝试以下操作。

> 1 == '1'
  true
> 1 === '1'
  false

== 必须检查比 ===

从一些脆弱的测试来看,==似乎比===.

稍微说一下,我的意思是我可以在数百万次测试的交互中看到几毫秒的差异。您不可能需要性能提升,而不是使用最适合手头任务的方法。

编辑:实际上,似乎取决于您正在比较的 /what/ 和浏览器实现。换句话说,不要担心。

@cdosborn 哇,你好 2011。这个 Q 早于 SO 上的 nodejs 标签。是的,你是对的。当时,这是一个公平的假设,这是在浏览器中,并且削减毫秒/数百万次评估将......浪费你的时间。在大约 5 年的时间里,事情发生了很多变化。
2021-04-30 17:49:18
“别担心”,“你不可能需要性能提升”。你不知道这个用户的意图,以及所有来这里问这个问题的用户。
2021-05-05 17:49:18
===在大多数情况下更快。有一些边缘情况(你找到了一个)。然而,从代码实践/风格指南中===,每次都获胜
2021-05-13 17:49:18