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

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


当前回答

我写这个方法只是为了确保数组和对象都能被清晰地比较。

这应该也能做到!:)

public class Objects {
    /**
     * Checks whether a value is of type Object
     * @param value the value
     */
    public static isObject = (value: any): boolean => {
        return value === Object(value) && Object.prototype.toString.call(value) !== '[object Array]'
    }

    /**
     * Checks whether a value is of type Array
     * @param value the value
     */
    public static isArray = (value: any): boolean => {
        return Object.prototype.toString.call(value) === '[object Array]' && !Objects.isObject(value)
    }

    /**
     * Check whether two values are equal
     */
    public static isEqual = (objectA: any, objectB: any) => {
        // Objects
        if (Objects.isObject(objectA) && !Objects.isObject(objectB)) {
            return false
        }
        else if (!Objects.isObject(objectA) && Objects.isObject(objectB)) {
            return false
        }
        // Arrays
        else if (Objects.isArray(objectA) && !Objects.isArray(objectB)) {
            return false
        }
        else if (!Objects.isArray(objectA) && Objects.isArray(objectB)) {
            return false
        }
        // Primitives
        else if (!Objects.isArray(objectA) && !Objects.isObject(objectA)) {
            return objectA === objectB
        }
        // Object or array
        else {
            const compareObject = (objectA: any, objectB: any): boolean => {
                if (Object.keys(objectA).length !== Object.keys(objectB).length) return false

                for (const propertyName of Object.keys(objectA)) {
                    const valueA = objectA[propertyName]
                    const valueB = objectB[propertyName]

                    if (!Objects.isEqual(valueA, valueB)) {
                        return false
                    }
                }

                return true
            }
            const compareArray = (arrayA: any[], arrayB: any[]): boolean => {
                if (arrayA.length !== arrayB.length) return false

                for (const index in arrayA) {
                    const valueA = arrayA[index]
                    const valueB = arrayB[index]

                    if (!Objects.isEqual(valueA, valueB)) {
                        return false
                    }
                }

                return true
            }
            if (Objects.isObject(objectA)) {
                return compareObject(objectA, objectB)
            } else {
                return compareArray(objectA, objectB)
            }
        }
    }
}

其他回答

var object1 = {name: "humza" , gender : "male", age: 23}
var object2 = {name: "humza" , gender : "male", age: 23}
var result = Object.keys(object1).every((key) =>  object1[key] === object2[key])

如果object1在object2上具有相同的值,Result将为true。

我使用这个可比函数来生成JSON可比的对象副本:

Var可比= o => (typeof o != '对象' || !o)?o: 种(o) .sort()。减少((c键)= > (c[主要]=可比(o(例子)),c), {}); / /演示: var = {1, c: 4 b:[2、3],d: {e:“5”,f:零}}; var b = {b:[2、3],c: 4 d: {f: null, e:“5”},答:1}; console.log (JSON.stringify(可比(a))); console.log (JSON.stringify(可比(b))); console.log(JSON.stringify(comparable(a)) == JSON.stringify(comparable(b))); < div id = " div " > < / div >

在测试中很方便(大多数测试框架都有一个is函数)。如。

is(JSON.stringify(comparable(x)), JSON.stringify(comparable(y)), 'x must match y');

如果捕捉到差异,则记录字符串,使差异可见:

x must match y
got      {"a":1,"b":{"0":2,"1":3},"c":7,"d":{"e":"5","f":null}},
expected {"a":1,"b":{"0":2,"1":3},"c":4,"d":{"e":"5","f":null}}.

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

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

注意:

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

纯JS方法:我的答案是基于生成一个返回相同值的字符串,无论属性顺序是否相同。设置对象可用于切换大小写和空白是否重要。(为了避免失去焦点,我没有包括那些支持函数,或者我猜应该在任何实用程序集中的isObject。)

这里也没有显示,但为了减少字符串比较时间,如果对象很大,你想加快比较,你也可以散列字符串和比较子字符串;这只适用于非常大的对象(当然也有很小的机会出现错误的相等)。

然后你可以比较genObjStr(obj1) ?= genObjStr(obj2)

function genObjStr(obj, settings) {
// Generate a string that corresponds to an object guarenteed to be the same str even if
// the object have different ordering. The string would largely be used for comparison purposes

var settings = settings||{};
var doStripWhiteSpace = defTrue(settings.doStripWhiteSpace);
var doSetLowerCase = settings.doSetLowerCase||false;

if(isArray(obj)) {
    var vals = [];
    for(var i = 0; i < obj.length; ++i) {
        vals.push(genObjStr(obj[i], settings));
    }
    vals = arraySort(vals);
    return vals.join(`,`);

} else if(isObject(obj)) {

    var keys = Object.keys(obj);
    keys = arraySort(keys);

    var vals = [];
    for(var key of keys) {
        
        var value = obj[key];
        
        value = genObjStr(value, settings);

        if(doStripWhiteSpace) {
            key = removeWhitespace(key);
            var value = removeWhitespace(value);
        };
        if(doSetLowerCase) {
            key = key.toLowerCase();
            value = value.toLowerCase();
        }

        vals.push(value);
    }
    var str = JSON.stringify({keys: keys, vals: vals});
    return str
} else {
    if(doStripWhiteSpace) {
        obj = removeWhitespace(obj);
    };
    if(doSetLowerCase) {
        obj = obj.toLowerCase();
    }
    return obj
}

}

var obj1 = {foo: 123, bar: `Test`};
var obj2 = {bar: `Test`, foo: 123};

console.log(genObjStr(obj1) == genObjStr(obj1))

是的,另一个答案……

Object.prototype.equals = function (object) { if (this.constructor !== object.constructor) return false; if (Object.keys(this).length !== Object.keys(object).length) return false; var obk; for (obk in object) { if (this[obk] !== object[obk]) return false; } return true; } var aaa = JSON.parse('{"name":"mike","tel":"1324356584"}'); var bbb = JSON.parse('{"tel":"1324356584","name":"mike"}'); var ccc = JSON.parse('{"name":"mike","tel":"584"}'); var ddd = JSON.parse('{"name":"mike","tel":"1324356584", "work":"nope"}'); $("#ab").text(aaa.equals(bbb)); $("#ba").text(bbb.equals(aaa)); $("#bc").text(bbb.equals(ccc)); $("#ad").text(aaa.equals(ddd)); <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> aaa equals bbb? <span id="ab"></span> <br/> bbb equals aaa? <span id="ba"></span> <br/> bbb equals ccc? <span id="bc"></span> <br/> aaa equals ddd? <span id="ad"></span>