严格相等运算符将告诉您两个对象类型是否相等。然而,是否有一种方法来判断两个对象是否相等,就像Java中的哈希码值一样?
堆栈溢出问题JavaScript中有hashCode函数吗?类似于这个问题,但需要一个更学术的答案。上面的场景说明了为什么有必要有一个,我想知道是否有等效的解决方案。
严格相等运算符将告诉您两个对象类型是否相等。然而,是否有一种方法来判断两个对象是否相等,就像Java中的哈希码值一样?
堆栈溢出问题JavaScript中有hashCode函数吗?类似于这个问题,但需要一个更学术的答案。上面的场景说明了为什么有必要有一个,我想知道是否有等效的解决方案。
当前回答
简而言之,这将检查两个变量是否相等,无论其类型如何。
function isSame (obj1, obj2) {
const obj1Keys = Object.keys(obj1)
const obj2Keys = Object.keys(obj2)
return obj1Keys.length === obj2Keys.length && obj1Keys.every((key) => obj1[key] === obj2[key])
}
其他回答
在对象中(没有方法),我们需要检查嵌套的对象,数组和基本类型。对象可以有其他对象和数组(数组也可以包括其他对象和数组),所以我们可以使用如下所示的递归函数:arrayEquals检查数组是否相等,equals检查对象是否相等:
function arrayEquals(a, b) {
if (a.length != b.length) {
return false;
}
for (let i = 0; i < a.length; i++) {
if (a[i].constructor !== b[i].constructor) {
return false;
}
if (a[i] instanceof Array && b[i] instanceof Array) {
if (!arrayEquals(a, b)) {
return false;
}
} else if (a[i] instanceof Object && b[i] instanceof Object) {
if (!equals(a[i], b[i])) {
return false;
}
} else if (a[i] !== b[i]) {
return false;
}
}
return true;
}
function equals(a, b) {
for (let el in a) {
if (b.hasOwnProperty(el)) {
if (a[el].constructor !== b[el].constructor) {
return false;
}
if (a[el] instanceof Array && b[el] instanceof Array) {
if (!arrayEquals(a[el], b[el])) {
return false;
}
} else if (a[el] instanceof Object && b[el] instanceof Object) {
if (!equals(a[el], b[el])) {
return false;
}
} else if (a[el] !== b[el]) {
return false;
}
} else {
return false;
}
}
return true;
}
假设你有两个对象:
let a = {
a: 1,
b: { c: 1, d: "test" },
c: 3,
d: [{ a: [1, 2], e: 2 }, "test", { c: 3, q: 5 }],
};
let b = {
a: 1,
b: { c: 1, d: "test" },
c: 3,
d: [{ a: [1, 2], e: 2 }, "test", { c: 3, q: 5 }],
};
在这里使用上面的equals函数,你可以很容易地比较这两个对象,像这样:
if(equals(a, b)) {
// do whatever you want
}
let std1 = {
name: "Abhijeet",
roll: 1
}
let std2 = {
name: "Siddharth",
roll: 2
}
console.log(JSON.stringify(std1) === JSON.stringify(std2))
Stringify两个对象并进行比较
返回(JSON.stringify(obj1) === = JSON.stringify(obj2))
这将返回true或false
我的版本,包括发现差异的地方,以及差异是什么。
function DeepObjectCompare(O1, O2)
{
try {
DOC_Val(O1, O2, ['O1->O2', O1, O2]);
return DOC_Val(O2, O1, ['O2->O1', O1, O2]);
} catch(e) {
console.log(e.Chain);
throw(e);
}
}
function DOC_Error(Reason, Chain, Val1, Val2)
{
this.Reason=Reason;
this.Chain=Chain;
this.Val1=Val1;
this.Val2=Val2;
}
function DOC_Val(Val1, Val2, Chain)
{
function DoThrow(Reason, NewChain) { throw(new DOC_Error(Reason, NewChain!==undefined ? NewChain : Chain, Val1, Val2)); }
if(typeof(Val1)!==typeof(Val2))
return DoThrow('Type Mismatch');
if(Val1===null || Val1===undefined)
return Val1!==Val2 ? DoThrow('Null/undefined mismatch') : true;
if(Val1.constructor!==Val2.constructor)
return DoThrow('Constructor mismatch');
switch(typeof(Val1))
{
case 'object':
for(var m in Val1)
{
if(!Val1.hasOwnProperty(m))
continue;
var CurChain=Chain.concat([m]);
if(!Val2.hasOwnProperty(m))
return DoThrow('Val2 missing property', CurChain);
DOC_Val(Val1[m], Val2[m], CurChain);
}
return true;
case 'number':
if(Number.isNaN(Val1))
return !Number.isNaN(Val2) ? DoThrow('NaN mismatch') : true;
case 'string':
case 'boolean':
return Val1!==Val2 ? DoThrow('Value mismatch') : true;
case 'function':
if(Val1.prototype!==Val2.prototype)
return DoThrow('Prototype mismatch');
if(Val1!==Val2)
return DoThrow('Function mismatch');
return true;
default:
return DoThrow('Val1 is unknown type');
}
}
我写了一个运行在Node.js和浏览器上的小库,叫做compare.js。它提供了常见的比较运算符,例如==,!=,>,>=,<,<=和所有JavaScript数据类型的标识符。
例如,你可以用
cmp.eq(obj1, obj2);
这将检查是否相等(使用深度相等的方法)。否则,如果你这样做
cmp.id(obj1, obj2);
它将通过引用进行比较,从而检查标识。 您还可以在对象上使用<和>,它们表示子集和超集。
Compare.js被近700个单元测试覆盖,因此它应该不会有太多的bug;-)。
你可以在https://github.com/goloroden/compare.js上免费找到它,它是MIT许可下的开源软件。