在JavaScript中比较对象

33

我有这段代码:

var object1 = {same:'test'}
var object2 = {same:'test'};       
console.log(object1 === object2)

它在控制台中返回false

我还有这段代码:

var object1 = {same:'test'}
var object2 = object1;
console.log(object1 === object2)  

它在控制台中返回true

我知道 '===' 是一个相等运算符,但我不知道它如何在对象上工作。

为什么第一个示例返回false?


3
对象始终通过引用进行比较,而不是通过相等性。 - Willem D'Haeseleer
已移除错误的“重复”标记。 - Niet the Dark Absol
3
@NiettheDarkAbsol,这个错误的重复标记吗?在SO上有很多类似的问题(例如这个问题,也被标记为重复:https://dev59.com/o3NA5IYBdhLWcg3wKacx?lq=1)。这个问题有什么不同之处? - Getz
好的,这并不是完全相同的问题。在你提供的链接中,楼主问道:“我知道‘如果两个对象引用的是同一个对象,则它们相等’,但是否有其他方法可以检查它?”而在这篇文章中,楼主并不知道“如果两个对象引用的是同一个对象,则它们相等”,这就是他所问的。 - dgiugg
1
如果您需要另一个示例,这是完全相同的问题:http://stackoverflow.com/questions/22828341/why-are-two-objects-with-the-same-values-not-equal - Getz
显示剩余3条评论
10个回答

83

看这个球吗?它的颜色是红色。称它为ball1。

看这个球吗?它的颜色也是红色。称它为ball2。

ball1和ball2是同一个物体吗?不,它们是不同的物体,只是恰好具有相同的属性。


看这个球吗?它的颜色是红色。称它为ball1。

让我们把ball1称为ball2。

ball1和ball2是同一个物体吗?是的。它们是同一个球。


31
好的比喻。还要考虑一下,如果我们决定给球2涂上绿色,会发生什么影响对于球1。 - tobyink
1
很棒的比喻(我完全抄袭了它) :) - Dimitar Dimitrov
+1。如果能够解释如何询问“这两个球看起来和行为一样吗?”则会获得额外积分。 - knittl
2
适用于许多编程语言,不仅限于JavaScript。这篇文章应该被添加到Stackoverflow的维基中:D - Suresh Atta
这是一个不错的比喻,但也许解释一下计算机在给变量赋值时实际上正在做什么,这样OP就可以更多地了解他们两个示例底层发生了什么。 - beporter

36

对象的比较是基于引用相等性进行的,因此object1object2是两个不同的实例,它们是不同的对象(可以将其视为:它们占据内存中的不同位置)。

然而,如果您将object1分配给object2,则它们都指向内存中的同一位置,因此它们是相等的(它们是对同一个单一对象的两个引用,在内存中只存在一次)。通过object1.same = 'uiae';更改属性将同时更新object2.same(因为它们实际上是同一个对象并具有相同的属性)。


9
var object1 ={same:'test'}
var object2 ={same:'test'};       
console.log(object1 === object2)

在这种情况下,您正在创建两个不同的对象。因此,在使用 === 操作符进行检查时,控制台返回 false 值。
var object1 ={same:'test'}
var object2 =object1;
console.log(object1 === object2)

在这种情况下,您正在创建一个对象,并且对象1和对象2引用已创建的对象,因此在使用===运算符进行检查时返回true。
在第二种情况下,如果我们更改object2 ["same"] =“test2”,那么object1 ["same"]的值也将更改为test2。
在第一种情况下,不会发生这种情况,因为object1和object2是两个不同的对象。
参考: JavaScript中的对象相等性 希望这可能有所帮助。

6
在第一种情况下,Object1和Object2是指向内存中两个不同对象的两个不同引用点(或变量)。因此,当您检查它们是否相等时,结果为false。
在第二种情况下,您只是将Object1的引用点(地址)复制到Object2,这意味着两个引用点现在都指向内存中的同一个对象。因此,结果为true。
对象始终通过引用进行比较。

4

当您将一个变量中的对象或数组分配给另一个变量时,它会复制对原始对象的引用,因此这两个对象是相等的。

每次编写对象或数组文字时,它都会生成一个不同的对象或数组,因此它们不相等,即使内容相似。


3

当您以这种方式创建对象时,您已经创建了一个映射表。 像这样的映射表没有像基本类型一样的值。因此,等式只会检查引用的相等性。因此,这将失败。 在第二种情况下,引用相等性得到了确认。


3

根据JavaScript的定义,两个不同的对象不能相等。相同的属性和值并不重要,因为它们有不同的指针(第一个例子)。

在第二个例子中,您正在克隆具有参考的对象。因此,"==="将返回true。


2

在你的第一个示例中,你创建了两个具有任意内容的不同对象,这些内容随机相同:{same:'test'}{same:'test'}

在你的第二个示例中,你只创建了一个对象,并将其存储在两个变量中:object1object2

=== 检查对象标识,这意味着在比较的变量中的对象必须是相同的。


1
=====运算符的区别在于前者执行类型强制转换,而后者执行严格比较(类型和值;对象的值恰好是它们的引用)。 - knittl
没有预定义的内容。您可以找到一些用户编写的函数来检查它。一个简单的解决方法(忽略函数并在不同顺序的字段上中断)是将两个对象转换为JSON字符串,然后比较结果字符串。 - knittl
@NathanCooper:是的,这就是为什么我指出它“忽略函数并在不同顺序的字段上中断”的原因。 - knittl
@knittl 哦,那就继续吧。我会删除我那条愚蠢的评论。 - Nathan Cooper
1
+1 因为这是唯一一个包含“identity”一词的答案。 - DaoWen
显示剩余2条评论

2

你的例子与 == vs === 运算符的区别无关。如前所述,你的例子只是创建了两个不同的对象,并在下一个示例中引用了相同的对象。在这种情况下,== 和 === 的行为都是相同的。

由于对象字面量始终是对象字面量,而且没有任何隐式转换的方式,因此对于对象字面量,== 和 === 总是会表现出相同的行为。在某些其他类型(如 NaN、null 等)中,使用 == 和 === 进行比较时会得到奇怪/有趣的结果。


0

这是 JavaScript 如何处理和比较对象的方式:

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接