JSON-objekt != JavaScript-objekt?


For enkelhets skyld skrev jeg en enkel toJSON-prototype for å håndtere JSON som jeg vet er sikker:

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

Jeg bruker det til å teste mine webtjenester. Dessverre selv med denne enkle testen:

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

Det mislykkes:

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

Hva vet jeg ikke om JavaScript som forårsaker dette problemet?

Svar #1

Bare fordi du har det samme innholdet, betyr ikke det at du har den samme objektinstansen. Hvis du hadde gjort v1=v0 i stedet for å initialisere v1 separat, ville de to første ha returnert sant.

Oppdatering: Hvis du trenger å sammenligne de to forekomstene for å finne ut om de har likt innhold, må du definere en funksjon som sammenligner hvert medlem.

Svar #2

Et objekt i JavaScript, akkurat som alt annet bortsett fra primitiver (int, string, Boolean), er en referanse.

Å ha 2 forskjellige duplikatobjekter betyr å ha 2 forskjellige referanser som peker til forskjellige steder innen hypen.

Du kan implementere noe så enkelt som det, for i praksis å gå gjennom alle de primitive egenskapene til et objekt, og sammenligne dem én etter én:

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