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

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


当前回答

const isEqual = function (var1, var2) {
    if (typeof var1 === 'object' && typeof var2 === 'object') {
        // Checking equality for each of the inner values of the objects
        const keys = [...new Set([...Object.keys(var1),...Object.keys(var2)])];
        return keys.every(key => isEqual(var1[key], var2[key]) && isEqual(var2[key], var1[key]));
    } else { // Primitive types (number, boolean etc..)
        return var1 === var2; // Normal equality
    }
}

我在这里看到了很多很好的答案,但我找不到一个简短的函数,所以我创建了一个。 这将检查两个变量是否相等,无论其类型如何。 希望你看得合适。

其他回答

排序对象(字典) 比较JSON字符串 函数areTwoDictsEqual(dictA, dictB) { 函数sortDict(dict) { var keys = Object.keys(dict); keys.sort (); var newDict = {}; For (var i=0;我< keys.length;我+ +){ Var key = keys[i]; Var值= dict[key]; newDict[key] = value; } 返回newDict; } 返回JSON.stringify(sortDict(dictA)) == JSON.stringify(sortDict(dictB)); }

我发现比较两个javascript对象的值而忽略属性顺序的一个简单方法是使用JSON stringify replacer函数:

const compareReplacer = (key, value) => {
    if(typeof value === 'object' && !(value instanceof Array))
        return Object.entries(value).sort();
    return value;
}
export const compareObjects = (a, b) => JSON.stringify(a, compareReplacer) === JSON.stringify(b, compareReplacer);

这将在每一步对属性进行排序,以便字符串结果对属性顺序不变。以前可能有人这样做过,但我只是想分享一下,以防万一:)。

只是想利用一些es6的特性来贡献我的对象比较版本。它不考虑订单。在将所有if/else转换为三元后,我带来了以下内容:

function areEqual(obj1, obj2) {

    return Object.keys(obj1).every(key => {

            return obj2.hasOwnProperty(key) ?
                typeof obj1[key] === 'object' ?
                    areEqual(obj1[key], obj2[key]) :
                obj1[key] === obj2[key] :
                false;

        }
    )
}

我写了一个运行在Node.js和浏览器上的小库,叫做compare.js。它提供了常见的比较运算符,例如==,!=,>,>=,<,<=和所有JavaScript数据类型的标识符。

例如,你可以用

cmp.eq(obj1, obj2);

这将检查是否相等(使用深度相等的方法)。否则,如果你这样做

cmp.id(obj1, obj2);

它将通过引用进行比较,从而检查标识。 您还可以在对象上使用<和>,它们表示子集和超集。

Compare.js被近700个单元测试覆盖,因此它应该不会有太多的bug;-)。

你可以在https://github.com/goloroden/compare.js上免费找到它,它是MIT许可下的开源软件。

下面是一个使用ES6+的解决方案

// this comparison would not work for function and symbol comparisons
// this would only work best for compared objects that do not belong to same address in memory
// Returns true if there is no difference, and false otherwise


export const isObjSame = (obj1, obj2) => {
    if (typeof obj1 !== "object" && obj1 !== obj2) {
        return false;
    }

    if (typeof obj1 !== "object" && typeof obj2 !== "object" && obj1 === obj2) {
        return true;
    }

    if (typeof obj1 === "object" && typeof obj2 === "object") {
        if (Array.isArray(obj1) && Array.isArray(obj2)) {
            if (obj1.length === obj2.length) {
                if (obj1.length === 0) {
                    return true;
                }
                const firstElemType = typeof obj1[0];

                if (typeof firstElemType !== "object") {
                    const confirmSameType = currentType =>
                        typeof currentType === firstElemType;

                    const checkObjOne = obj1.every(confirmSameType);
                    const checkObjTwo = obj2.every(confirmSameType);

                    if (checkObjOne && checkObjTwo) {
                        // they are primitves, we can therefore sort before and compare by index
                        // use number sort
                        // use alphabet sort
                        // use regular sort
                        if (firstElemType === "string") {
                            obj1.sort((a, b) => a.localeCompare(b));
                            obj2.sort((a, b) => a.localeCompare(b));
                        }
                        obj1.sort((a, b) => a - b);
                        obj2.sort((a, b) => a - b);

                        let equal = true;

                        obj1.map((element, index) => {
                            if (!isObjSame(element, obj2[index])) {
                                equal = false;
                            }
                        });

                        return equal;
                    }

                    if (
                        (checkObjOne && !checkObjTwo) ||
                        (!checkObjOne && checkObjTwo)
                    ) {
                        return false;
                    }

                    if (!checkObjOne && !checkObjTwo) {
                        for (let i = 0; i <= obj1.length; i++) {
                            const compareIt = isObjSame(obj1[i], obj2[i]);
                            if (!compareIt) {
                                return false;
                            }
                        }

                        return true;
                    }

                    // if()
                }
                const newValue = isObjSame(obj1, obj2);
                return newValue;
            } else {
                return false;
            }
        }

        if (!Array.isArray(obj1) && !Array.isArray(obj2)) {
            let equal = true;
            if (obj1 && obj2) {
                const allKeys1 = Array.from(Object.keys(obj1));
                const allKeys2 = Array.from(Object.keys(obj2));

                if (allKeys1.length === allKeys2.length) {
                    allKeys1.sort((a, b) => a - b);
                    allKeys2.sort((a, b) => a - b);

                    allKeys1.map((key, index) => {
                        if (
                            key.toLowerCase() !== allKeys2[index].toLowerCase()
                        ) {
                            equal = false;
                            return;
                        }

                        const confirmEquality = isObjSame(obj1[key], obj2[key]);

                        if (!confirmEquality) {
                            equal = confirmEquality;
                            return;
                        }
                    });
                }
            }

            return equal;

            // return false;
        }
    }
};