Specifically, the problem this is solving is the common usage of
if (JSON.stringify(x) === JSON.stringify(y))
which makes me grit my teeth every time I see it, especially on collections of unbounded size. (Perhaps the problem being solved is my dental health.)
There is no standard deep-equality function in standard ECMAScript. The right way to solve the deep-equality problem is probably to write object- and class-specific equality tests, but in the absence of that, people can and do just stringify both objects and see if the string matches.
I understand some of the difficulting in specifying a standard deep-equality function. What exactly does "equality" mean? Which members get reference-checked, and which get value-checked? Does a difference in private fields break equality? Can an object override its native equality behavior? Are object cycles allowed? All extremely important questions that absolutely need to get answered before we can have something like an Object.equals
.
And in the meantime, people will continue to write the following, found in a commit from 2022:
// Why is this something i have to write
equals(thing1, thing2) {
return JSON.stringify(thing1) === JSON.stringify(thing2);
}
And, despite the steadily-decreasing tread depth of my teeth, I can't argue that there's one major benefit from comparing things this way: if people have written toJSON()
methods on their classes, then it probably means that those methods will return all the significant data, i.e. all the data that probably wants to be compared if you're trying to tell if something has changed.
I would never suggest that a default of some hypothetical generic Object.equals()
should respect toJSON()
methods - I'd find that behavior very surprising, in a bad way. But, in cases where we do want to compare "the exported data of these two objects", like, say, if you're trying to decide whether you need to autosave a game, or whether your cache needs refreshing, then a JSON.equals()
method would be exactly what I want. "Is the hypothetical JSON output of this object equal to the hypothetical JSON output of this other one? No, please don't allocate two 10MB string buffers, all I want is the yes/no." It might also want a version that compares an object against a JSON string, for when you've kept your previous save-export around.
Sorry for the brevity of my original post! I have difficulty knowing when I need to elaborate vs when I need to be succinct, and I erred too far on the latter side this time ![:sweat_smile: :sweat_smile:](https://emoji.discourse-cdn.com/apple/sweat_smile.png?v=12)