严格相等运算符将告诉您两个对象类型是否相等。然而,是否有一种方法来判断两个对象是否相等,就像Java中的哈希码值一样?
堆栈溢出问题JavaScript中有hashCode函数吗?类似于这个问题,但需要一个更学术的答案。上面的场景说明了为什么有必要有一个,我想知道是否有等效的解决方案。
严格相等运算符将告诉您两个对象类型是否相等。然而,是否有一种方法来判断两个对象是否相等,就像Java中的哈希码值一样?
堆栈溢出问题JavaScript中有hashCode函数吗?类似于这个问题,但需要一个更学术的答案。上面的场景说明了为什么有必要有一个,我想知道是否有等效的解决方案。
当前回答
当然,当我们在它的时候,我会抛出我自己对车轮的重新发明(我为辐条和使用的材料的数量感到自豪):
////////////////////////////////////////////////////////////////////////////////
var equals = function ( objectA, objectB ) {
var result = false,
keysA,
keysB;
// Check if they are pointing at the same variable. If they are, no need to test further.
if ( objectA === objectB ) {
return true;
}
// Check if they are the same type. If they are not, no need to test further.
if ( typeof objectA !== typeof objectB ) {
return false;
}
// Check what kind of variables they are to see what sort of comparison we should make.
if ( typeof objectA === "object" ) {
// Check if they have the same constructor, so that we are comparing apples with apples.
if ( objectA.constructor === objectA.constructor ) {
// If we are working with Arrays...
if ( objectA instanceof Array ) {
// Check the arrays are the same length. If not, they cannot be the same.
if ( objectA.length === objectB.length ) {
// Compare each element. They must be identical. If not, the comparison stops immediately and returns false.
return objectA.every(
function ( element, i ) {
return equals( element, objectB[ i ] );
}
);
}
// They are not the same length, and so are not identical.
else {
return false;
}
}
// If we are working with RegExps...
else if ( objectA instanceof RegExp ) {
// Return the results of a string comparison of the expression.
return ( objectA.toString() === objectB.toString() );
}
// Else we are working with other types of objects...
else {
// Get the keys as arrays from both objects. This uses Object.keys, so no old browsers here.
keysA = Object.keys( objectA );
keysB = Object.keys( objectB );
// Check the key arrays are the same length. If not, they cannot be the same.
if ( keysA.length === keysB.length ) {
// Compare each property. They must be identical. If not, the comparison stops immediately and returns false.
return keysA.every(
function ( element ) {
return equals( objectA[ element ], objectB[ element ] );
}
);
}
// They do not have the same number of keys, and so are not identical.
else {
return false;
}
}
}
// They don't have the same constructor.
else {
return false;
}
}
// If they are both functions, let us do a string comparison.
else if ( typeof objectA === "function" ) {
return ( objectA.toString() === objectB.toString() );
}
// If a simple variable type, compare directly without coercion.
else {
return ( objectA === objectB );
}
// Return a default if nothing has already been returned.
return result;
};
////////////////////////////////////////////////////////////////////////////////
它会尽可能快地返回false,但当然,对于一个差异嵌套很深的大对象,它可能不那么有效。在我自己的场景中,良好地处理嵌套数组非常重要。
希望它能帮助需要这种“轮子”的人。
其他回答
ES6:我能做到的最小代码是这样的。它通过对代表对象的所有键值数组进行字符串化来进行递归的深度比较,唯一的限制是没有方法或符号进行比较。
const compareObjects = (a, b) => { let s = (o) => Object.entries(o).sort()。映射(i => { if(i[1]实例对象)i[1] = s(i[1]); 返回我 }) 返回JSON.stringify(s(a)) === JSON.stringify(s(b)) } console.log (compareObjects ({b: 4,答:{b: 1}}, {} {b: 1, b: 4}));
重要提示:这个函数正在执行JSON。stringfy在数组中,并将键排序,而不是在对象本身中:
["a" ["b", 1]] [" b ", 4]
这是一个非常干净的CoffeeScript版本,你可以这样做:
Object::equals = (other) ->
typeOf = Object::toString
return false if typeOf.call(this) isnt typeOf.call(other)
return `this == other` unless typeOf.call(other) is '[object Object]' or
typeOf.call(other) is '[object Array]'
(return false unless this[key].equals other[key]) for key, value of this
(return false if typeof this[key] is 'undefined') for key of other
true
下面是测试:
describe "equals", ->
it "should consider two numbers to be equal", ->
assert 5.equals(5)
it "should consider two empty objects to be equal", ->
assert {}.equals({})
it "should consider two objects with one key to be equal", ->
assert {a: "banana"}.equals {a: "banana"}
it "should consider two objects with keys in different orders to be equal", ->
assert {a: "banana", kendall: "garrus"}.equals {kendall: "garrus", a: "banana"}
it "should consider two objects with nested objects to be equal", ->
assert {a: {fruit: "banana"}}.equals {a: {fruit: "banana"}}
it "should consider two objects with nested objects that are jumbled to be equal", ->
assert {a: {a: "banana", kendall: "garrus"}}.equals {a: {kendall: "garrus", a: "banana"}}
it "should consider two objects with arrays as values to be equal", ->
assert {a: ["apple", "banana"]}.equals {a: ["apple", "banana"]}
it "should not consider an object to be equal to null", ->
assert !({a: "banana"}.equals null)
it "should not consider two objects with different keys to be equal", ->
assert !({a: "banana"}.equals {})
it "should not consider two objects with different values to be equal", ->
assert !({a: "banana"}.equals {a: "grapefruit"})
最简单和逻辑的解决方案,比较一切像对象,数组,字符串,Int…
JSON。stringify({a: val1}) == JSON。stringify ({a: val2})
注意:
你需要用你的Object替换val1和val2 对于对象,必须对两侧对象进行递归排序(按键)
如果你的问题是检查两个对象是否相等,那么这个函数可能会有用
function equals(a, b) {
const aKeys = Object.keys(a)
const bKeys = Object.keys(b)
if(aKeys.length != bKeys.length) {
return false
}
for(let i = 0;i < aKeys.length;i++) {
if(aKeys[i] != bKeys[i]) {
return false
}
}
for(let i = 0;i < aKeys.length;i++) {
if(a[aKeys[i]] != b[bKeys[i]]) {
return false
}
}
return true
}
first we check if the length of the list of keys of these objects is the same, if not we return false to check if two objects are equal they must have the same keys(=names) and the same values of the keys, so we get all the keys of objA, and objB and then we check if they are equal once we find that tow keys are not equal then we return false and then when all the keys are equal then we loop through one of the keys of one of the objects and then we check if they are equal once they are not we return false and after the two loops finished this means they are equal and we return true NOTE: this function works with only objects with no functions
let std1 = {
name: "Abhijeet",
roll: 1
}
let std2 = {
name: "Siddharth",
roll: 2
}
console.log(JSON.stringify(std1) === JSON.stringify(std2))