编辑:供参考,这是 Axel Rauschmayer 博士的规范解释
http://www.2ality.com/2011/06/javascript-equality.html
写得真好。
===(严格相等):仅考虑具有相同类型的相等值。
- 未定义 === 未定义,空 === 空,
- NaN === 没有,包括它自己,
- 原始 [Number|String|Boolean] === 原始值相等,
- 对自己 (+0 === -0)
- 两个对象 [Array|Object|Function] === 只有自己(完全相同的实体)
==(宽大平等)
- 如果两个值的类型相同:与 === 比较。
- 未定义 == 空
- 数字和字符串:字符串 => 数字和比较
- boolean and non-boolean => non-boolean to number and compare
- 字符串或数字 => 对象:将对象转换为原始对象并进行比较。
在所有现代 Javascript 环境中,它们的实现方式完全不同。简单来说,== 通过将给定变量转换为原语(字符串、数字、布尔值)来测试相似性。 === 测试严格相同,这意味着完全相同的 Object 或原始值,无需转换。
如果你这样做
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 中唯一不可变的东西。