这并不新鲜。
非原始对象(即对象)的等价性比较它们在字面上是否是相同的实际对象。这不是一个新概念。对 JS 中的其他非原始内容同样适用:
var a = [1,2,3];
var b = [1,2,3];
console.log(a == b); // -> false
var c = {foo:'bar'};
var d = {foo:'bar'};
console.log(c == d); // -> false
为什么基元/对象比较不同?
简单:因为 2 个图元是否“相同”的概念与 2 个对象是否“相同”的概念不同。
您实际上可以对同一个对象进行多次引用,因此检查两个引用是否“相同”具有与原语非常不同的含义。它们实际上可能是指向同一个对象的实际指针:
var str1 = 'foo';
var str2 = str1;
str2 += ' bar';
console.log(str2); // -> "foo bar"
console.log(str1); // -> still just "foo"
// str1 is unchanged, primitives don't do pointers
var obj1 = {val:'foo'};
var obj2 = obj1;
obj2.val += ' bar';
console.log(obj2.val); // -> "foo bar"
console.log(obj1.val); // -> "foo bar"
// obj1 and obj2 are LITERALLY pointers to the same thing
// changing one changes the other
因此,对于原语(它们存在的一个完整点是值足够原始,即使它们实际上并未在内部指向相同的实际 1 和 0,我们也可以比较它们)可能与当我们问“它们是否等价”时,非基元(其中 2 个值可能在内部从字面上指向相同的 1 和 0)?
更不用说技术上的困难了。
基元之所以这样称呼是有原因的:它们是简单/原始的值。因此,它们很容易比较。
对象在设计上要复杂得多。他们甚至可以持有对其他对象的引用……甚至是对自己的引用。以您暗示的方式比较它们应该是一个可能无限的迭代过程,而不是简单的操作员操作。考虑一下:
var a = {foo:'bar'};
a.a = a;
console.log(a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.foo); // -> bar
// could go on forever that way
制作诸如检查等效性之类的东西突然意味着可能无限的迭代过程将对语言产生深远的负面影响。更有意义的是,它们只是检查它们是否字面上相等(即指向同一个确切的对象)。