我可以在ES6中创建集合:
let s = new Set([1, 2, 3]);
let q = new Set([3, 1, 2]);
但无法通过它们包含的内容来比较它们。
console.log(s == q); // --> false
API中没有提供.equals(other)
方法,仅提供.has()
,delete()
等。对我来说,似乎很容易实现 - 为什么不呢?
(我不是在寻找解决方法,就像this回答中提供的解决方法一样。我只是想知道为什么做出这个决定,因为我肯定不了解它周围的情况。 )
答案 0 :(得分:1)
非基元(即对象)的等效性比较它们是否实际上是相同的实际对象。这不是一个新概念。对于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个对象是否“相同”的概念不同。
实际上你可以对同一个对象进行多次引用,因此检查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
像检查等效性这样的东西突然意味着可能无限的迭代过程会对语言产生深远的负面影响。更有意义的是,他们只是检查它们是否在字面上相等(即指向同一个确切的对象)。