严格相等运算符将告诉您两个对象类型是否相等。然而,是否有一种方法来判断两个对象是否相等,就像Java中的哈希码值一样?
堆栈溢出问题JavaScript中有hashCode函数吗?类似于这个问题,但需要一个更学术的答案。上面的场景说明了为什么有必要有一个,我想知道是否有等效的解决方案。
严格相等运算符将告诉您两个对象类型是否相等。然而,是否有一种方法来判断两个对象是否相等,就像Java中的哈希码值一样?
堆栈溢出问题JavaScript中有hashCode函数吗?类似于这个问题,但需要一个更学术的答案。上面的场景说明了为什么有必要有一个,我想知道是否有等效的解决方案。
当前回答
假设对象中属性的顺序没有改变。
JSON.stringify()适用于深度和非深度这两种类型的对象,不太确定性能方面:
Var object1 = { 关键:“价值” }; Var object2 = { 关键:“价值” }; Var object3 = { 键:“无值” }; console.log('object1和object2相等:',JSON.stringify(object1) === JSON.stringify(object2)); console.log('object2和object3相等:',JSON.stringify(object2) === JSON.stringify(object3));
其他回答
这取决于你对平等的定义。因此,作为类的开发人员,要由您来定义它们的相等性。
有时会使用一种情况,如果两个实例指向内存中的相同位置,则认为它们是“相等的”,但这并不总是您想要的。例如,如果我有一个Person类,如果两个Person对象具有相同的Last Name、First Name和Social Security Number(即使它们指向内存中的不同位置),我可能会认为它们是“相等的”。
另一方面,我们不能简单地说两个对象是相等的,如果它们的每个成员的值都相同,因为,有时,你并不想这样。换句话说,对于每个类,由类开发人员定义组成对象“标识”的成员并开发适当的相等操作符(通过重载==操作符或Equals方法)。
Saying that two objects are equal if they have the same hash is one way out. However you then have to wonder how the hash is calculated for each instance. Going back to the Person example above, we could use this system if the hash was calculated by looking at the values of the First Name, Last Name, and Social Security Number fields. On top of that, we are then relying on the quality of the hashing method (that's a huge topic on its own, but suffice it to say that not all hashes are created equal, and bad hashing methods can lead to more collisions, which in this case would return false matches).
下面是ES6/ES2015中使用函数式方法的解决方案:
const typeOf = x =>
({}).toString
.call(x)
.match(/\[object (\w+)\]/)[1]
function areSimilar(a, b) {
const everyKey = f => Object.keys(a).every(f)
switch(typeOf(a)) {
case 'Array':
return a.length === b.length &&
everyKey(k => areSimilar(a.sort()[k], b.sort()[k]));
case 'Object':
return Object.keys(a).length === Object.keys(b).length &&
everyKey(k => areSimilar(a[k], b[k]));
default:
return a === b;
}
}
这里有演示
const one={name:'mohit' , age:30};
//const two ={name:'mohit',age:30};
const two ={age:30,name:'mohit'};
function isEquivalent(a, b) {
// Create arrays of property names
var aProps = Object.getOwnPropertyNames(a);
var bProps = Object.getOwnPropertyNames(b);
// If number of properties is different,
// objects are not equivalent
if (aProps.length != bProps.length) {
return false;
}
for (var i = 0; i < aProps.length; i++) {
var propName = aProps[i];
// If values of same property are not equal,
// objects are not equivalent
if (a[propName] !== b[propName]) {
return false;
}
}
// If we made it this far, objects
// are considered equivalent
return true;
}
console.log(isEquivalent(one,two))
我建议不要使用散列或序列化(正如JSON解决方案所建议的那样)。如果需要测试两个对象是否相等,则需要定义相等的含义。这可能是两个对象中的所有数据成员都匹配,也可能是内存位置必须匹配(意味着两个变量在内存中引用同一个对象),或者每个对象中只有一个数据成员必须匹配。
最近我开发了一个对象,它的构造函数在每次创建实例时都会创建一个新的id(从1开始,加1)。该对象有一个isEqual函数,用于将该id值与另一个对象的id值进行比较,如果匹配则返回true。
在这种情况下,我定义“相等”的意思是id值匹配。假设每个实例都有一个唯一的id,这可以用来加强匹配对象也占用相同内存位置的想法。尽管这是不必要的。
这是对以上所有内容的补充,而不是替代。如果需要快速浅比较对象,而不需要检查额外的递归情况。这是一个镜头。
这比较:1)自己的属性数量相等,2)键名相等,3)如果bCompareValues == true,对应的属性值及其类型相等(三重相等)
var shallowCompareObjects = function(o1, o2, bCompareValues) {
var s,
n1 = 0,
n2 = 0,
b = true;
for (s in o1) { n1 ++; }
for (s in o2) {
if (!o1.hasOwnProperty(s)) {
b = false;
break;
}
if (bCompareValues && o1[s] !== o2[s]) {
b = false;
break;
}
n2 ++;
}
return b && n1 == n2;
}