“==”的对象相等的标准定义是啥?

Posted

技术标签:

【中文标题】“==”的对象相等的标准定义是啥?【英文标题】:What is the standard definition of object equality for "=="?“==”的对象相等的标准定义是什么? 【发布时间】:2011-11-05 22:58:19 【问题描述】:

似乎== 的普遍理解与其实际作用不匹配。为这个问题提供一些背景:

typeof new Number(1); // returns object
typeof new String(1); // returns object
typeof 1;             // returns number

看起来NumberString 都属于object 类型。那里并不奇怪。然而,== 的事情变得有趣了,当操作数不管它们的类型相等时,它应该返回 true

据a somewhat authorative description:

运营商试图 将对象转换为原始值、字符串或数字值, 使用对象的 valueOf 和 toString 方法。如果这次尝试 转换对象失败,会产生运行时错误。

简而言之,== 应该通过对象的原始值来比较对象。令人惊讶的是:

var numa = new Number(1);
var numb = new Number(1);
var stri = new String(1);

numa.toString() == stri.toString(); // returns true, as expected
numa.valueOf() == stri.valueOf();   // returns true, as expected

numa == stri; // returns false (?!)
numa == numb; // returns false (?!!!)

numa == numa; // returns true, as expected

var numx = 1;

numa == numx; // returns true (?)
numb == numx; // returns true (?)
stri == numx; // returns true (?)

当两个操作数都是对象时出现,== 运算符既不使用 toString() 也不使用 valueOf(),而是使用其他东西。

== 对象相等的标准定义是什么?

【问题讨论】:

为什么要投赞成票?答案是“阅读规范”。 @Tim Down:大多数技术问题都归结为“阅读规范”,不用说。没必要吝啬。我的意思是,SO 的全部意义不在于获得专家的答案——以换取乐趣和利润吗? 当您询问“标准定义”是什么时,真的无处可去。任何不参考规范的答案都将是不精确的或使用非标准术语。我想在一些人认为更容易理解的术语中解释规范的答案可能有一些价值。 【参考方案1】:

简而言之,当操作数是对象时,== 会比较引用。

来自official specification,第 80 页:

11.9.3 抽象等式比较算法

如果 Type(x) 与 Type(y) 相同,那么

a - e 省略,因为不适用于对象

f.如果 x 和 y 引用同一个对象,则返回 true。 否则,返回 false。

【讨论】:

==不是严格相等的。该问题表明,当两个操作数都是对象时,javascript 使用 neither valueOf() nor toString(). 严格相等意味着值相等与类型相等new Number(1).valueOf() === new Number(1).valueOf() 返回 true,这意味着操作数具有相等的值new Number(1) instanceof Number; 还返回 true,这意味着根据定义,操作数具有相等类型。但是== 仍然失败。因此,关于对象相等性的标准定义的问题。 看看更新。那是你的standard definition。从中可以看出,如果两个操作数都是对象,则不会转换对象。 太好了,这就是我想要的。 @Saul:所以我告诉你同样的事情,首先,有更多的反馈,这个答案得到了接受,因为它引用了一个规范。***的风格多么令人恼火。【参考方案2】:

我相信您在那里看到的以及“有点权威的描述”中遗漏的是== 尝试将一个对象转换为一个基元,当且仅当它的比较对象是一个基元时。如果两个操作数都是对象,则将它们作为对象进行比较,并且只有当它们是相同的对象时,相等性测试才为真(即相同的实例——具有相同属性的不同对象是不同的,正如您在 numa == numb 案例中看到的那样)。

【讨论】:

我假设大致相同。但是我不明白 究竟是什么 JavaScript 在那里比较。它使用的是哪个标识符?该标识符是否可以从“外部”以某种方式访问​​,例如通过console.log? @Saul:我希望它比较的是分配对象的内存地址或 JS 引擎内部的 ID。我不知道有任何 JS 控制台可以使用它;它通常被视为“您不需要知道”的信息。

以上是关于“==”的对象相等的标准定义是啥?的主要内容,如果未能解决你的问题,请参考以下文章

检查联合实例之间是不是相等的正确方法是啥?

hadoop reducer 不考虑两个相等的自定义可写对象相等

为啥java 里要判断两个对象是不是相等呢?

|=(单管道相等)和 &=(单与号相等)是啥意思

预处理器相等性测试,这是标准吗?

对象的新增方法《ES6标准入门(第3版)》