JavaScript:测试基元的相等性

时间:2011-01-02 22:07:38

标签: javascript comparison

假设我有两个对象只有基元作为成员的属性(例如,对象没有函数或对象成员):

var foo = {
    start: 9,
    end: 11
};

var bar = {
    start: 9, 
    end: 11
};

考虑到这样的两个对象,我想知道他们的所有成员是否都有相同的值。

现在我正在做:

if (foo.start === bar.start && foo.end == bar.end) {
    // same member values
}

但是我将不得不处理可能有几十个原始成员的对象。

JavaScript中是否有任何内容可以让我轻松比较它们?比较所有价值观的最简单方法是什么?

3 个答案:

答案 0 :(得分:6)

如果两个对象都是Object s(例如,通过文字符号[{}]或new Object创建,而不是[说] new Date),则可以执行此操作像这样:

function primativelyEqual(a, b) {
    var name;
    for (name in a) {
        if (!b.hasOwnProperty(name) || b[name] !== a[name]) {
            // `b` doesn't have it or it's not the same
            return false;
        }
    }
    for (name in b) {
        if (!a.hasOwnProperty(name)) {
            // `a` doesn't have it
            return false;
        }
    }

    // All properties in both objects are present in the other,
    // and have the same value down to the type
    return true;
}

for..in迭代对象属性的名称。 hasOwnProperty告诉您实例本身(与其原型链的成员相对)是否具有该属性。 !==检查两个值之间的任何不等式,而不进行任何类型强制。通过循环遍历两个对象的属性名称,您知道它们具有相同数量的条目。

如果实现具有来自ECMAScript5的新Object.keys功能,您可以将其快捷一点:

function primativelyEqual(a, b) {
    var name, checkedKeys;

    checkedKeys = typeof Object.keys === "function";
    if (checkedKeys && Object.keys(a).length !== Object.keys(b).length) {
        // They don't have the same number of properties
        return false;
    }
    for (name in a) {
        if (!b.hasOwnProperty(name) || b[name] !== a[name]) {
            // `b` doesn't have it or it's not the same
            return false;
        }
    }
    if (!checkedKeys) {
        // Couldn't check for equal numbers of keys before
        for (name in b) {
            if (!a.hasOwnProperty(name)) {
                // `a` doesn't have it
                return false;
            }
        }
    }

    // All properties in both objects are present in the other,
    // and have the same value down to the type
    return true;
}

Live example

但上面的两个版本都假设对象没有从原型中继承任何可枚举的属性(因此我的开场陈述是关于它们的Object)。 (我也假设没有人向Object.prototype添加任何东西,这是人们很快就学会了不做的疯狂事情。)

绝对有可能进一步优化它以概括它,甚至使它通过相同的定义下降到对象属性,但是在你描述的范围内(并且在大多数合理的部署的范围内),这应该没问题。

答案 1 :(得分:3)

您可以使用for in循环遍历对象中的每个属性。

例如:

function areEqual(a, b) {
    for (var prop in a) 
        if (a.hasOwnProperty(prop) && a[prop] !== b[prop])
            return false;
    return true;
}

ba中的所有属性都将被忽略。

答案 2 :(得分:0)

你知道吗,我刚刚想到了什么。基本对象文字称为JSON。比较这两个对象的最简单方法是

function equalObjects(obj1, obj2) {
    return JSON.stringify(obj1) === JSON.stringify(obj2);    
}

如果您需要在没有本机JSON支持的浏览器中使用此功能,可以使用open source JSON scripts