Possible Duplicate:
How do you determine equality for two JavaScript objects?
Object comparison in JavaScript
If I have two arrays or objects and want to compare them, such as
object1 = [
{ shoes:
[ 'loafer', 'penny' ]
},
{ beers:
[ 'budweiser', 'busch' ]
}
]
object2 = [
{ shoes:
[ 'loafer', 'penny' ]
},
{ beers:
[ 'budweiser', 'busch' ]
}
]
object1 == object2 // false
this can be annoying if you’re getting a response from a server and trying to see if it’s changed
Update:
In response to the comments and worries surrounding the original suggestion (comparing 2 JSON strings), you could use this function:
But in many cases, it needn’t be that difficult IMO:
If the stringified objects are the same, their values are alike.
For completeness’ sake:
JSONsimply ignores functions (well, removes them all together). It’s meant to represent Data, not functionality.Attempting to compare 2 objects that contain only functions will result in
true:For deep-comparison of objects/functions, you’ll have to turn to libs or write your own function, and overcome the fact that JS objects are all references, so when comparing
o1 === ob2it’ll only return true if both variables point to the same object…As @a-j pointed out in the comment:
is
false, as both stringify calls yield"{"a":1,"b":2}"and"{"b":2,"a":1}"respectively. As to why this is, you need to understand the internals of chrome’s V8 engine. I’m not an expert, and without going into too much detail, here’s what it boils down to:Each object that is created, and each time it is modified, V8 creates a new hidden C++ class (sort of). If object X has a property
a, and another object has the same property, both these JS objects will reference a hidden class that inherits from a shared hidden class that defines this propertya. If two objects all share the same basic properties, then they will all reference the same hidden classes, andJSON.stringifywill work exactly the same on both objects. That’s a given (More details on V8’s internals here, if you’re interested).However, in the example pointed out by a-j, both objects are stringified differently. How come? Well, put simply, these objects never exist at the same time:
This is a function call, an expression that needs to be resolved to the resulting value before it can be compared to the right-hand operand. The second object literal isn’t on the table yet.
The object is stringified, and the exoression is resolved to a string constant. The object literal isn’t being referenced anywhere and is flagged for garbage collection.
After this, the right hand operand (the
JSON.stringify({b: 2, a: 1})expression) gets the same treatment.All fine and dandy, but what also needs to be taken into consideration is that JS engines now are far more sophisticated than they used to be. Again, I’m no V8 expert, but I think its plausible that a-j’s snippet is being heavily optimized, in that the code is optimized to:
Essentially omitting the
JSON.stringifycalls all together, and just adding quotes in the right places. That is, after all, a lot more efficient.