JSON объект!= JavaScript объект?

Для удобства я написал простую toJSON прототип, для обработки JSON, который я знаю, чтобы быть безопасным:

String.prototype.toJSON = function () {
    return JSON.parse(this.valueOf());
};

Я использую его при тестировании своих веб-сервисов. К сожалению, даже с этим простым тестом:

var v0 = '{"echo":"hello_world"}'.toJSON(), v1 = {"echo": "hello_world"};

Это не удается:

console.log(v0 == v1);            // false
console.log(v0 === v1);           // false
console.log(v0.echo == v1.echo);  // true
console.log(v0.echo === v1.echo); // true

Что я не знаю о JavaScript, который вызывает эту проблему?

3 ответа

Решение

Объект в JavaScript, как и все остальное, кроме примитивов (int, string, Boolean), является ссылкой.

Наличие двух разных дублирующих объектов означает наличие двух разных ссылок, которые указывают на разные места в рекламе.

Вы можете реализовать что-то столь же простое, чтобы в основном перебирать все примитивные свойства объекта и сравнивать их одно за другим:

Object.prototype.equals = function(x)
{
    for(p in this)
    {
        switch(typeof(this[p]))
        {
            case 'object':
                if (!this[p].equals(x[p])) { return false }; break;
            case 'function':
                if (typeof(x[p])=='undefined' || (p != 'equals' && this[p].toString() != x[p].toString())) { return false; }; break;
            default:
                if (this[p] != x[p]) { return false; }
        }
    }

    for(p in x)
    {
        if(typeof(this[p])=='undefined') {return false;}
    }

    return true;
}

То, что у вас одинаковое содержимое, не означает, что у вас один и тот же экземпляр объекта. Если бы вы сделали v1 = v0 вместо инициализации v1 отдельно первые два вернули бы истину.

Обновление: если вам нужно сравнить два экземпляра, чтобы определить, имеют ли они одинаковое содержание, вам нужно определить функцию, которая сравнивает каждого члена.

Чтобы два объекта были == они должны быть одним и тем же экземпляром. v0 и v1 два разных экземпляра. Если вы хотите сделать глубокое сравнение объектов, вы можете использовать что-то вроде подчеркивания isEqual: http://underscorejs.org/

_.isEqual(v0, v1);
Другие вопросы по тегам