严格相等运算符将告诉您两个对象类型是否相等。然而,是否有一种方法来判断两个对象是否相等,就像Java中的哈希码值一样?
堆栈溢出问题JavaScript中有hashCode函数吗?类似于这个问题,但需要一个更学术的答案。上面的场景说明了为什么有必要有一个,我想知道是否有等效的解决方案。
严格相等运算符将告诉您两个对象类型是否相等。然而,是否有一种方法来判断两个对象是否相等,就像Java中的哈希码值一样?
堆栈溢出问题JavaScript中有hashCode函数吗?类似于这个问题,但需要一个更学术的答案。上面的场景说明了为什么有必要有一个,我想知道是否有等效的解决方案。
当前回答
let std1 = {
name: "Abhijeet",
roll: 1
}
let std2 = {
name: "Siddharth",
roll: 2
}
console.log(JSON.stringify(std1) === JSON.stringify(std2))
其他回答
如果你真的想比较并返回两个对象的差值。 您可以使用这个包:https://www.npmjs.com/package/deep-diff
或者只使用这个包使用的代码
https://github.com/flitbit/diff/blob/master/index.js
只是不要把它转换成字符串进行比较。
我有一个更短的函数,它将深入到所有子对象或数组。它和JSON.stringify(obj1) === JSON.stringify(obj2)一样高效,但是JSON.stringify(obj2)。如果顺序不相同(如此处所述),Stringify将无法工作。
var obj1 = { a : 1, b : 2 };
var obj2 = { b : 2, a : 1 };
console.log(JSON.stringify(obj1) === JSON.stringify(obj2)); // false
这个函数也是一个很好的开始如果你想处理不相等的值。
function arr_or_obj(v) { return !!v && (v.constructor === Object || v.constructor === Array); } function deep_equal(v1, v2) { if (arr_or_obj(v1) && arr_or_obj(v2) && v1.constructor === v2.constructor) { if (Object.keys(v1).length === Object.keys(v2).length) // check the length for (var i in v1) { if (!deep_equal(v1[i], v2[i])) { return false; } } else { return false; } } else if (v1 !== v2) { return false; } return true; } ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// var obj1 = [ { hat : { cap : ['something', null ], helmet : [ 'triple eight', 'pro-tec' ] }, shoes : [ 'loafer', 'penny' ] }, { beers : [ 'budweiser', 'busch' ], wines : [ 'barefoot', 'yellow tail' ] } ]; var obj2 = [ { shoes : [ 'loafer', 'penny' ], // same even if the order is different hat : { cap : ['something', null ], helmet : [ 'triple eight', 'pro-tec' ] } }, { beers : [ 'budweiser', 'busch' ], wines : [ 'barefoot', 'yellow tail' ] } ]; console.log(deep_equal(obj1, obj2)); // true console.log(JSON.stringify(obj1) === JSON.stringify(obj2)); // false console.log(deep_equal([], [])); // true console.log(deep_equal({}, {})); // true console.log(deep_equal([], {})); // false
如果你想增加对Function, Date和RegExp的支持,你可以在deep_equal的开头添加这个(未测试):
if ((typeof obj1 === 'function' && typeof obj2 === 'function') ||
(obj1 instanceof Date && obj2 instanceof Date) ||
(obj1 instanceof RegExp && obj2 instanceof RegExp))
{
obj1 = obj1.toString();
obj2 = obj2.toString();
}
简短的回答
简单的答案是:不,没有一般的方法来确定一个对象等于另一个你所指的意义。例外情况是当您严格地认为一个对象是无类型的。
长话短说
这个概念是一个Equals方法,它比较一个对象的两个不同实例,以指示它们在值级别上是否相等。但是,定义Equals方法应该如何实现取决于具体的类型。对具有基本值的属性进行迭代比较可能还不够:对象可能包含与相等无关的属性。例如,
function MyClass(a, b)
{
var c;
this.getCLazy = function() {
if (c === undefined) c = a * b // imagine * is really expensive
return c;
}
}
在上面的例子中,c对于确定MyClass的任何两个实例是否相等并不重要,只有a和b是重要的。在某些情况下,c可能在不同实例之间有所不同,但在比较中并不显著。
注意,当成员本身也可能是某个类型的实例,并且每个实例都需要有确定相等的方法时,这个问题就会出现。
更复杂的是,在JavaScript中,数据和方法之间的区别是模糊的。
一个对象可以引用一个作为事件处理程序调用的方法,这可能不被认为是其“值状态”的一部分。然而,另一个对象很可能被分配一个执行重要计算的函数,从而使这个实例与其他实例不同,仅仅因为它引用了不同的函数。
如果一个对象的现有原型方法被另一个函数覆盖,该怎么办?它还能被认为与另一个相同的实例相等吗?这个问题只能在每种类型的具体情况下回答。
如前所述,异常将是一个严格的无类型对象。在这种情况下,唯一明智的选择是对每个成员进行迭代和递归比较。即使这样,人们也要问一个函数的“值”是什么?
为什么要重新发明轮子?试试Lodash吧。它有许多必须的函数,如isEqual()。
_.isEqual(object, other);
它将使用ECMAScript 5和本地优化(如果它们在浏览器中可用)强力检查每个键值——就像本页上的其他示例一样。
注意:以前这个答案推荐使用Underscore.js,但是lodash在修复bug和一致性解决问题方面做得更好。
如果要比较JSON对象,可以使用https://github.com/mirek/node-rus-diff
npm install rus-diff
用法:
a = {foo:{bar:1}}
b = {foo:{bar:1}}
c = {foo:{bar:2}}
var rusDiff = require('rus-diff').rusDiff
console.log(rusDiff(a, b)) // -> false, meaning a and b are equal
console.log(rusDiff(a, c)) // -> { '$set': { 'foo.bar': 2 } }
如果两个对象不同,MongoDB兼容{$rename:{…},设置美元:{…},美元:{…返回}}like对象。