JavaScript - === vs ==运营商的表现

got*_*tqn 23 javascript performance equality comparison-operators equality-operator

几个星期前,我已经读过这个帖子<快于<=?关于比较运算符C.据说它们之间的性能没有区别<,<=因为它们被解释为相同/相似的机器命令.

同时,在我们公司的"最佳实践"中,据说我们应该总是使用"==="来比较事物而不是"==".所以,我开始怀疑这是否总是合适的,因为我习惯使用"=="和"typeof ... =="并且不想改变我的写作方式: - ]

请注意,这是在JavaScript的上下文中.

那么,我有一点研究,这里应该在JavaScript比较中使用哪个等于运算符(== vs ===)?据说:

这是因为等于运算符==确实类型强制...意味着解释器隐式尝试转换值然后进行比较.

另一方面,身份运算符===不进行类型强制,因此它在比较时不会转换值的值

我开始怀疑这是否意味着当我使用"==="运算符时,我将获得良好的性能,因为没有资源将用于转换操作数.而所有的代码变成机器命令后,这是否意味着就像存在没有区别C,当你使用<<=,这是JavaScript和其他语言一样吗?

Tim*_*own 13

首先,表现根本不是一个问题.对于任何真实的脚本,与代码中的其他瓶颈相比,使用一个运算符而不是另一个运算符的任何性能增益都是无限小的(通常DOM操作将是头号目标).

其次,在许多情况下,=====将执行完全相同的步骤.当两个操作数的类型相同时(例如,两个字符串或两个数字),ECMAScript规范对于两个操作符具有完全相同的步骤.因此,如果您在一个浏览器或其他环境中观察到两个运算符之间在相同类型的操作数之间的性能差异,则无法保证甚至可能在另一个浏览器中看到类似的差异.

typeof你的问题中提到的情况下,两个操作数保证是相同类型(字符串),并且两个操作符将完全相同,因此支持一个操作符而不是另一个操作符的唯一理由是风格.

作为一个整体的JS社区已经相当强硬:共识似乎是"永远不会使用==,!=除非你需要类型强制",这对我的口味来说太教条了.

  • 很多时候,我从服务器获得了大量数据.想象一千行,这一行中的每个值都应与其他值进行比较.如果信息以字符串形式返回,我将其与"=="进行比较,因为它毕竟是"数字",这意味着1000次隐蔽操作.这就是我认为性能很重要的原因. (2认同)

Ric*_*lde 12

我觉得答案很容易,可以证实的证据是最好的.

这些操作非常小,很难对它们进行性能测试.

  • == 1648是的
  • === 1629是的
  • 控制测试1575真实

如果你减去控制测试,看起来他们的浏览器速度差异约为30%.如果你多次这样做,你可以得到不同的答案,但===通常是最快的,我认为这只是对差异的微不足道的证明.

我认为这几乎证明了其他人在说什么,性能差异是浪费时间思考,但它也表明===实际上更快.希望这个答案可以节省其他人的时间,那些只需要看证明的人.

var testString = "42";
var testString2 = "43";
var testString3 = "42";
var testNumber = 42;
var testNumber2 = 43;
var testNumber3 = 42;

var testObject = {};
var testObject2 = {};
var testObject3 = testObject;


var start = Date.now();
var result = null;
for(var i = 0; i < 200000000; i++){
	result = 
	testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
	testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
	testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
	testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
	testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
	testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
	testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
	testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
	testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
	testString == testString2 || testNumber == testNumber2 || testObject == testObject2 || 
	testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
	testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
	testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
	testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
	testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
	testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
	testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
	testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
	testString == testString3 && testNumber == testNumber3 && testObject == testObject3 && 
	testString == testString3 && testNumber == testNumber3 && testObject == testObject3
}

console.log("==", Date.now() - start, result);

var start = Date.now();
var result = null;
for(var i = 0; i < 200000000; i++){
	result =
	testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
	testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
	testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
	testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
	testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
	testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
	testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
	testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
	testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
	testString === testString2 || testNumber === testNumber2 || testObject === testObject2 || 
	testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
	testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
	testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
	testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
	testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
	testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
	testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
	testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
	testString === testString3 && testNumber === testNumber3 && testObject === testObject3 && 
	testString === testString3 && testNumber === testNumber3 && testObject === testObject3
}
console.log("===", Date.now() - start, result);
var start = Date.now();
var alwaysTrue = true;
var alwaysFalse = false;
for(var i = 0; i < 200000000; i++){
	result = 
	alwaysFalse || alwaysFalse || alwaysFalse || 
	alwaysFalse || alwaysFalse || alwaysFalse || 
	alwaysFalse || alwaysFalse || alwaysFalse || 
	alwaysFalse || alwaysFalse || alwaysFalse || 
	alwaysFalse || alwaysFalse || alwaysFalse || 
	alwaysFalse || alwaysFalse || alwaysFalse || 
	alwaysFalse || alwaysFalse || alwaysFalse || 
	alwaysFalse || alwaysFalse || alwaysFalse || 
	alwaysFalse || alwaysFalse || alwaysFalse || 
	alwaysFalse || alwaysFalse || alwaysFalse || 
	alwaysTrue && alwaysTrue && alwaysTrue && 
	alwaysTrue && alwaysTrue && alwaysTrue && 
	alwaysTrue && alwaysTrue && alwaysTrue && 
	alwaysTrue && alwaysTrue && alwaysTrue && 
	alwaysTrue && alwaysTrue && alwaysTrue && 
	alwaysTrue && alwaysTrue && alwaysTrue && 
	alwaysTrue && alwaysTrue && alwaysTrue && 
	alwaysTrue && alwaysTrue && alwaysTrue && 
	alwaysTrue && alwaysTrue && alwaysTrue && 
	alwaysTrue && alwaysTrue && alwaysTrue
}
console.log("control test", Date.now() - start, result);
Run Code Online (Sandbox Code Playgroud)


gbj*_*anb -4

对于 js 来说,如果在字符串类型上使用 === 运算符并且字符串是完全相同的字符,则 === 运算符将返回 true。对于对象,它比较对象引用,而不是内容。

来自ECMA 标准

11.9.6 严格相等比较算法 x === y 的比较(其中 x 和 y 是值)产生 true 或 false。这样的比较执行如下:

  1. 如果 Type(x) 与 Type(y) 不同,则返回 false。
  2. 如果 Type(x) 未定义,则返回 true。
  3. 如果 Type(x) 为 Null,则返回 true。
  4. 如果 Type(x) 是 Number,则 a. 如果 x 为 NaN,则返回 false。b. 如果 y 为 NaN,则返回 false。C。如果 x 与 y 的 Number 值相同,则返回 true。d. 如果 x 为 +0 并且 y 为 -0,则返回 true。e. 如果 x 为 -0 并且 y 为 +0,则返回 true。F。返回假。
  5. 如果 Type(x) 是 String,则 x 和 y 是完全相同的字符序列(长度相同且对应位置的字符相同),则返回 true;否则,返回 false。
  6. 如果 Type(x) 为 Boolean,则 x 和 y 均为 true 或均为 false 时返回 true;

  • 这包含一些错误的信息(而且这个小编辑是事后的想法)。不要求“str === str”仅对同一对象为真。`"a" + "b" === "ab"` 为 true,但不要求 `"a" + "b"` 与 `"ab"` 驻留在同一个对象中。如果*实现*决定两者是相同的对象值,则*两者*`==`和`===`都可以“提前停止”(这将是在*某些*情况下有效的特定于实现的优化) ,否则字符串值必须与“===”逐个字符进行比较。 (7认同)
  • @Joro 运算符“===”和“==”仅在操作数类型不同时有所不同(例如*String* 与*Number*)。如果比较两个 *Object* 值,它们的行为相同 - `obj1 == obj2` 相当于 `obj1 === obj2`。其他类型也是如此 - `str1 == str2` 相当于 `str1 === str2` 等。这就是第一段出错的地方(至少在 JavaScript 的上下文中)。 (3认同)
  • 第一段几乎完全不正确。如果您有兴趣,我可以提供详细的解释。(你是否一直在用不同的语言来写作?) (2认同)