简体   繁体   English

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

[英]JavaScript performance difference between double equals (==) and triple equals (===)

In JavaScript, is there a performance difference between using a double equals ( == ) vs using a triple equals ( === )? 在JavaScript中,使用double equals( == )与使用triple equals( === )之间是否存在性能差异?

Example: if (foo == bar) vs if (foo === bar) 示例: if (foo == bar) vs if (foo === bar)

  • If the types compared are the same, they are identical . 如果比较的类型相同,则它们是相同的 That is to say they use the exact same algorithm . 也就是说他们使用完全相同的算法

  • If the types are different , then performance is irrelevant. 如果类型不同 ,那么性能就无关紧要了。 Either you need type coercion, or you don't. 要么你需要类型强制,要么你不需要。 If you don't need it, don't use == because the result you get may be unexpected. 如果您不需要它,请不要使用==因为您获得的结果可能是意外的。

Strict comparison ( === ) will always be slightly faster, but the difference is usually negligible . 严格比较( === )总是稍微快一些,但差异通常可以忽略不计

It definitely makes sense to prefer === if you know for certain that you don't need type coercion in the comparison. 如果您确定在比较中不需要类型强制,那么首选===肯定是有道理的。 It will always be at least as fast as == . 它总是至少和==一样快。

Edit: for reference here's the by the spec explanation by Dr. Axel Rauschmayer http://www.2ality.com/2011/06/javascript-equality.html Really great write up. 编辑:供参考,这是 Axel Rauschmayer博士的规范解释http://www.2ality.com/2011/06/javascript-equality.html非常好写。

=== (Strict Equality): Only considers values equal that have the same type. === (严格平等):仅考虑具有相同类型的相等值。

  1. undefined === undefined, null === null, undefined === undefined,null === null,
  2. NaN === nothing including itself, NaN ===没有包括它自己,
  3. Primitive [Number|String|Boolean] === primitive value equal, Primitive [Number | String | Boolean] ===原始值相等,
  4. to self (+0 === -0) 自我(+0 === -0)
  5. Two objects [Array|Object|Function] === Only self (same exact entity) 两个对象[Array | Object | Function] ===只有self(同一个确切的实体)

== (Lenient Equality) == (宽容平等)

  1. If both values have the same type: compare with ===. 如果两个值具有相同的类型:与===比较。
  2. undefined == null undefined == null
  3. number and string: string => number and compare number和string:string => number and compare
  4. boolean and non-boolean => non-boolean to number and compare boolean和non-boolean =>非布尔数字和比较
  5. string or number => an object: convert object to primitive and comparison. string或number =>一个对象:将对象转换为原始和比较。

In all modern Javascript environments they are implemented completely different. 在所有现代Javascript环境中,它们的实现完全不同。 In simple terms, == tests for alikeness via converting given variables into primitives (string, number, boolean). 简单来说, ==通过将给定变量转换为基元(字符串,数字,布尔值)来测试相似性。 === tests for strict sameness, which means exact same Object or primitive value without conversion. ===测试严格相同性,这意味着完全相同的Object或原始值而不进行转换。

If you do objOne == objTwo what actually happens is [[EQUALS]].call(objOne.valueOf(), objTwo.valueOf()) 如果你做objOne == objTwo ,实际发生的是[[EQUALS]].call(objOne.valueOf(), objTwo.valueOf())

The resolution of valueOf can be somewhat involved, bouncing between functions exposed in JS and internal engine stuff. valueOf的分辨率可能会有所涉及,在JS中暴露的函数和内部引擎之间反弹。 Suffice to say that the comparison will always end up with two values coerced to primitive or an error will be thrown. 可以说,比较将始终以两个强制转换为原始值或错误的方式结束。

Edit: EQUALS actually tries STRICT_EQUALS first which preempts the rest of the process. 编辑: EQUALS实际上首先尝试STRICT_EQUALS ,它会抢占进程的其余部分。

The interesting bit here is that valueOf (and its partner toString) are overridable. 这里有趣的是,valueOf(和它的伙伴toString)是可以覆盖的。 Run this piece of code in Chrome (I think any webkit, not sure if JSC and V8 share this tidbit). 在Chrome中运行这段代码(我认为任何webkit,不确定JSC和V8是否共享这个小窍门)。 It will blow your mindpiece: 它会打击你的思想:

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);

Output: 输出:

[ { 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 } ]

The essence of the difference between == and === is illustrated by === not showing up in that list. =====之间差异的本质通过===未显示在该列表中来说明。 It skips the journey into JavascriptLand entirely. 它完全跳过JavascriptLand的旅程。 That adventure is expensive when comparing performance. 比较性能时,这种冒险是昂贵的。

However you need to account for engine optimizations. 但是,您需要考虑引擎优化。 For most objects, the engine will be able to cut out most of the steps and stay in NativeLand and get almost the same performance. 对于大多数对象,引擎将能够删除大部分步骤并保留在NativeLand中并获得几乎相同的性能。 But this isn't a guarantee and if something prevents the engine from being able to use the optimizations, some fancyness in your code or overriding the builtins or a myriad of issues, then you instantly see the result in performance. 但这不是一种保证,如果有什么东西阻止引擎能够使用优化,代码中的一些花哨或覆盖内置或无数问题,那么你会立即看到性能结果。 === forces it. ===强迫它。

=== is just about the only immutable thing in Javascript. ===只是Javascript中唯一不可变的东西。

Due to performance, I think === has better performance, because === is stricter than == , 由于性能,我认为===有更好的性能,因为=====更严格,

eg try the following in the Chrome console. 例如,在Chrome控制台中尝试以下操作。

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

== has to check more things than === ==必须检查比===更多的东西

From some flimsy tests, == appears to be marginally quicker than === . 从一些脆弱的测试来看, ==似乎比===略快。

By marginally, I mean that I can see a few milliseconds difference on interations of many millions of tests. 稍微说,我的意思是我可以看到数百万次测试的内部差异几毫秒。 You can't possibly need the performance gain, rather than using whatever is most correct for the task at hand. 您不可能需要性能提升,而不是使用最适合手头任务的任何东西。

EDIT: actually, seems to depend on /what/ you're comparing and the browser implementation. 编辑:实际上,似乎依赖于/您正在比较和浏览器实现。 In other words, don't worry about it. 换句话说,不要担心。

It depends on the items being compared. 这取决于被比较的项目。 Since "===" is more strict than "==", it should return false faster than "==". 由于“===”比“==”更严格,因此它应该比“==”更快地返回false。 However, if the two items are strictly equal "===" should take more time than "==" because it has to check more properties for equality. 但是,如果两个项严格相等,“===”应该比“==”花费更多的时间,因为它必须检查更多属性是否相等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM