严格相等运算符将告诉您两个对象类型是否相等。然而,是否有一种方法来判断两个对象是否相等,就像Java中的哈希码值一样?

堆栈溢出问题JavaScript中有hashCode函数吗?类似于这个问题,但需要一个更学术的答案。上面的场景说明了为什么有必要有一个,我想知道是否有等效的解决方案。


当前回答

最简单和逻辑的解决方案,比较一切像对象,数组,字符串,Int…

JSON。stringify({a: val1}) == JSON。stringify ({a: val2})

注意:

你需要用你的Object替换val1和val2 对于对象,必须对两侧对象进行递归排序(按键)

其他回答

这是一个经典的javascript问题!我创建了一个方法来检查深度对象是否相等,其特性是能够从比较中选择要忽略的属性。 参数是要比较的两个对象,加上一个可选的字符串化属性-忽略相对路径数组。

function isObjectEqual( o1, o2, ignorePropsArr=[]) {
    // Deep Clone objects
    let _obj1 = JSON.parse(JSON.stringify(o1)),
        _obj2 = JSON.parse(JSON.stringify(o2));
    // Remove props to ignore
    ignorePropsArr.map( p => { 
        eval('_obj1.'+p+' = _obj2.'+p+' = "IGNORED"');
    });
    // compare as strings
    let s1 = JSON.stringify(_obj1),
        s2 = JSON.stringify(_obj2);
    // return [s1==s2,s1,s2];
    return s1==s2;
}

// Objects 0 and 1 are exact equals
obj0 = { price: 66544.10, RSIs: [0.000432334, 0.00046531], candles: {A: 543, B: 321, C: 4322}}
obj1 = { price: 66544.10, RSIs: [0.000432334, 0.00046531], candles: {A: 543, B: 321, C: 4322}}
obj2 = { price: 66544.12, RSIs: [0.000432334, 0.00046531], candles: {A: 543, B: 321, C: 4322}}
obj3 = { price: 66544.13, RSIs: [0.000432334, 0.00046531], candles: {A: 541, B: 321, C: 4322}}
obj4 = { price: 66544.14, RSIs: [0.000432334, 0.00046530], candles: {A: 543, B: 321, C: 4322}}

isObjectEqual(obj0,obj1) // true
isObjectEqual(obj0,obj2) // false
isObjectEqual(obj0,obj2,['price']) // true
isObjectEqual(obj0,obj3,['price']) // false
isObjectEqual(obj0,obj3,['price','candles.A']) // true
isObjectEqual(obj0,obj4,['price','RSIs[1]'])   // true
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

这是一个简单的Javascript函数,用于比较具有简单键值对的两个对象。该函数将返回一个字符串数组,其中每个字符串是到两个对象之间的一个不等式的路径。

function compare(a,b) {
    var paths = [];
    [...new Set(Object.keys(a).concat(Object.keys(b)))].forEach(key=>{
        if(typeof a[key] === 'object' && typeof b[key] === 'object') {
            var results = compare(a[key], b[key]);
            if(JSON.stringify(results)!=='[]') {
                paths.push(...results.map(result=>key.concat("=>"+result)));
            }
        }
        else if (a[key]!==b[key]) {
            paths.push(key);
        }
    })
    return paths;
}

如果你只想比较两个对象,而不知道不等式的路径,你可以这样做:

if(JSON.stringify(compare(object1, object2))==='[]') {
   // the two objects are equal
} else {
   // the two objects are not equal
}

下面是一个使用JSON的简短实现。stringify但按@Jor建议的方式对键进行排序。

一些测试来自@EbrahimByagowi的回答。

当然,通过使用JSON。stringify,解决方案仅限于JSON序列化类型(字符串、数字、JSON对象、数组、布尔值、null)。不支持Date、Function等对象。

function objectEquals(obj1, obj2) { const JSONstringifyOrder = obj => { const keys = {}; JSON.stringify(obj, (key, value) => { keys[key] = null; return value; }); return JSON.stringify(obj, Object.keys(keys).sort()); }; return JSONstringifyOrder(obj1) === JSONstringifyOrder(obj2); } /////////////////////////////////////////////////////////////// /// The borrowed tests, run them by clicking "Run code snippet" /////////////////////////////////////////////////////////////// var printResult = function (x) { if (x) { document.write('<div style="color: green;">Passed</div>'); } else { document.write('<div style="color: red;">Failed</div>'); } }; var assert = { isTrue: function (x) { printResult(x); }, isFalse: function (x) { printResult(!x); } } assert.isTrue(objectEquals("hi","hi")); assert.isTrue(objectEquals(5,5)); assert.isFalse(objectEquals(5,10)); assert.isTrue(objectEquals([],[])); assert.isTrue(objectEquals([1,2],[1,2])); assert.isFalse(objectEquals([1,2],[2,1])); assert.isFalse(objectEquals([1,2],[1,2,3])); assert.isTrue(objectEquals({},{})); assert.isTrue(objectEquals({a:1,b:2},{a:1,b:2})); assert.isTrue(objectEquals({a:1,b:2},{b:2,a:1})); assert.isFalse(objectEquals({a:1,b:2},{a:1,b:3})); assert.isTrue(objectEquals({1:{name:"mhc",age:28}, 2:{name:"arb",age:26}},{1:{name:"mhc",age:28}, 2:{name:"arb",age:26}})); assert.isFalse(objectEquals({1:{name:"mhc",age:28}, 2:{name:"arb",age:26}},{1:{name:"mhc",age:28}, 2:{name:"arb",age:27}}));