JavaScript: тестирование примитивов на равенство - PullRequest
0 голосов
/ 03 января 2011

Скажем, у меня есть два объекта, которые имеют только примитивы в качестве свойств для членов (например, у объекта нет функций или членов-объектов):

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 ]

6 голосов
/ 03 января 2011

Если оба объекта 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 сообщает вам, имеет ли это свойство сам экземпляр (в отличие от члена его цепочки прототипов).!== проверяет любое неравенство между двумя значениями без приведения типов.Зацикливая имена свойств обоих объектов, вы знаете, что они имеют одинаковое количество записей.

Вы можете немного сократить это, если реализация имеет новую функцию Object.keys из ECMAScript5:

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;
}

Живой пример

Но обе версии вышеупомянутого предполагают, что объекты не наследуют никаких перечисляемых свойств от своих прототипов (следовательно, мойвступительное заявление об их существовании Object с).(Я также предполагаю, что никто ничего не добавил к Object.prototype, что является безумной вещью, которую люди очень быстро научились не делать.)

Определенно возможно усовершенствовать это, обобщить его и даже заставить его спускаться.в свойства объекта по тому же определению, но в рамках того, что вы описали (и в рамках наиболее разумных развертываний), это должно быть хорошо.

3 голосов
/ 03 января 2011

Вы можете использовать цикл for in для просмотра всех свойств объекта.

Например:

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

Любые свойства в b, но не a будут игнорироваться.

0 голосов
/ 03 января 2011

Знаешь, что-то только что произошло со мной.Основные литералы объекта называются JSON.Самый простой способ сравнить эти два объекта:

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

Если вам нужно использовать это в браузере, который не имеет встроенной поддержки JSON, вы можете использовать JSON-скрипты с открытым исходным кодом

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...