Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON object != JavaScript object? [duplicate]

For convenience I wrote a simple toJSON prototype, for handling JSON that I know to be safe:

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

I am using it in testing my web-services. Unfortunately even with this simple test:

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

It fails:

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

What do I not know about JavaScript which is causing this issue?

like image 629
A T Avatar asked Dec 22 '13 11:12

A T


3 Answers

Just because you have the same content, that does not mean that you have the same object instance. If you had done v1 = v0 instead of initializing v1 seperatly the first two would have returned true.

Update: If you need to compare the two instances to find if they have equal content then you need to define a function which compares each member.

like image 198
fredrik Avatar answered Sep 22 '22 02:09

fredrik


An object in JavaScript, just like everything else except primitives(int, string, Boolean) is a reference.

Having 2 different duplicate objects, means having 2 different references that point to different places within the hype.

You can implement something as simple as that, to basically iterate over all of the primitive properties of an object, and compare them one by one:

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;
}
like image 42
Oleg Belousov Avatar answered Sep 21 '22 02:09

Oleg Belousov


For two objects to be == they must be the same instance. v0 and v1 are two different instances. If you want to do a deep comparison of objects you can use something like underscore's isEqual method: http://underscorejs.org/#isEqual

_.isEqual(v0, v1);
like image 40
Hallvar Helleseth Avatar answered Sep 23 '22 02:09

Hallvar Helleseth