Javascript 对象和基元类型相等

Javascript 对象和基元类型相等,javascript,object,equality,primitive,Javascript,Object,Equality,Primitive,我知道相同的对象并不相等,即: var obj = { name: "Value" }; var obj2 = { name: "Value" }; console.log("obj equals obj2: " + (obj === obj2)); //evaluates to false var str = "string1"; var str2 = "string1"; console.log("str equals str2: " + (str === str2)); //eval

我知道相同的对象并不相等,即:

var obj = { name: "Value" };
var obj2 = { name: "Value" };

console.log("obj equals obj2: " + (obj === obj2)); //evaluates to false
var str = "string1";
var str2 = "string1";

console.log("str equals str2: " + (str === str2)); //evaluates to true
但基本类型是:

var obj = { name: "Value" };
var obj2 = { name: "Value" };

console.log("obj equals obj2: " + (obj === obj2)); //evaluates to false
var str = "string1";
var str2 = "string1";

console.log("str equals str2: " + (str === str2)); //evaluates to true
我的问题是为什么。为什么对象和基本体的处理方式不同?如果一个对象只是一个空容器,只有您指定要放入容器中的属性,那么为什么容器的相同属性的计算结果不相同?我四处寻找这个答案,但没有找到答案

JS对象在DOM中是否被视为与基本类型不同的东西


谢谢

这似乎真的是一个关于
=
的问题,让我们看看,第7点说

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

那么“同一个物体”意味着什么呢?这意味着他们不仅长得很像,而且在记忆中也在同一个地方。这意味着只有当一个对象与一个对象是同一个对象时,它才是对象

var a = {},
    b = {}, // identical to `a`
    c = a;  // same as `a`
a === b; // false
a === c; // true
b === c; // false

当一个变量的值是一个对象时,它不是一个对象:它是对一个对象的引用。包含对同一对象引用的两个变量实际上相等:

var myObj = { hello: "world" };
var a = myObj;
var b = myObj;

if (a == b) alert("YES!!"); // YES!!

==
操作符两侧都有对象引用时,进行比较是为了测试对象是否引用同一对象。当涉及原语值时,语义是不同的:直接比较值。

通常,
==
运算符检查类型,如果类型相同,则检查值。对象类型包含一个引用,因此,要使其相等,它们必须引用同一个对象并具有相同的类型。字符串文字值不是引用,而是一个值,因此
==
将为字符串文字生成true,但不会为“abc”
===
新字符串(“abc”)生成true,因为后者是一个对象


更多信息可以在这里找到:很多细节可以在这里探索:

首先,JavaScript对象不是DOM的一部分。DOM(文档对象模型)是组成页面的HTML元素。他们一起合作,但没有直接联系

基本上,是的,原语是一种特例。你可以把它看作是一个常量(在某种意义上)

例如,以数字5为例。无论我声明了多少次5,5始终等于5。因此,说{var a持有值5}等同于{var b持有值5}并不过分。这个概念对于字符串来说有点模糊,但它仍然适用。“abc”字符串始终与包含“abc”字符串的任何其他变量相同

这也不适用于对象

如果有两个变量包含同一个对象,则它们是等价的

var a = {};
var b = a;
console.log(a == b); // true
console.log(a === b); // true
但是,如果我们创建两个外观相似的对象:

var a = {};
var b = {};
console.log(a == b); // false
console.log(a === b); // false
一开始这似乎有点奇怪,但想想正在进行的内部工作。当你把一个对象传递给一个函数时,如果你改变了这个对象,它就被函数的外部改变了。它是通过引用传递的

这意味着您可以将指针(内存地址)存储在变量中。所以,如果你想象它们里面有内存地址(比如0x123456和0x654321),那么它就更有意义了(0x123456和0x654321是不同的,所以你不会为了相等而花费它们)。它们是两个独立的东西,占据着各自的记忆区域


有意义吗?

你可以从几个层次回答这个问题

串 事实上,就严格比较运算符而言,字符串的处理方式与对象不同

从语义上讲,这比使用strcmp或等效机制来比较两个字符串更方便

就实现而言,成本是可以忽略的,因此JavaScript可以为您提供这种便利

顺便说一句,告诉严格相等运算符的人检查两个变量是否指向同一个内存位置是错误的。对于字符串,如果字符串内容在内存中的任何位置都相等,===将成功

物体 语义上,与数字或字符串等基本类型相反,很难为对象提供一组一致的比较运算符。
您可以对等式进行深入的比较,但大/小运算符没有什么意义

在这里,Javascript的选择相当不一致

  • 相等比较的语义(无论是
    =
    还是
    ==
    )仅限于引用
    (即,如果引用相等,
    ==
    ===
    将成功)
就实施而言,深入比较可能会花费相当大的成本。
还有一些微妙之处,比如如何解释未定义的属性

无论如何,JavaScript并没有选择实现深度比较,所以如果您需要,您必须自己进行比较。
已经有太多TB的代码编写出来,试图提供理想的深入对象比较功能

  • 有序比较的处理方式完全不同
您可以定义一个
valueOf
方法,该方法将返回要用于有序比较的任何基本值,例如

myObject.prototype.valueOf = function(){return this.my_comparison_value; };
如果未明确定义,
valueOf
将默认为
“[object object]”

因此,如果不提供
valueOf
方法:

  • 运算符将始终返回
    false
    (哪种类型有意义)
  • =
    =b&&a您询问语言的实现,因此我不确定,但是想象一下,必须对每个被比较对象的每个字段进行内部检查,然后必须定义什么是完全相等的。我猜设计师们决定离开obj的这种平衡