The last thing I did in my proposal was to ensure there were shallow and deep variants, as the language does not have either shallow or deep object-data comparison at the moment.
@conartista6 Agreed. The distinction between "does it represent the same information" and "will it continue to represent the same information" is exactly why frozen objects matter.
With frozen objects, the answer to both questions is the same β and it stays the same. That predictability is what makes caching, memoization, and deduplication safe. Without it, you are guessing.
I think this also clarifies the scope: Object.dataEqual is not for arbitrary objects. It is for data that has been explicitly frozen β a signal from the developer that says "this will not change, you can rely on it."
Still not thrilled about seeing so many signs of AI use on this forum tho. I don't think there's an official policy, but please in the future do not tell me that I am absolutely right.
@conartista6 That is a great point. If the language gains Object.dataEqual for deep comparison, it should also provide a shallow variant for completeness. Object.is already exists but compares references, not data. A shallow data comparison would compare own enumerable properties by value, one level deep.
Something like:
js
Object.dataEqual(a, b); // deep β recursive, requires frozen
Object.dataEqual(a, b, 1); // shallow β own properties only, one level
Or a separate method:
js
Object.dataEqual(a, b); // deep
Object.dataEqualShallow(a, b); // shallow
This mirrors what you did with Records β shallow and deep variants. It also covers the use case @ljharb mentioned with the shallow equality proposal, but scoped to frozen data objects.
It's helping in the sense that no proposal will ever advance if it fails to communicate a persuasive and compelling problem statement to the entire set of delegates, no matter how many people want it. Feel free to ignore the advice.
@ljharb Fair enough. Let me try again, shorter this time.
I have two objects. They came from different places β maybe one from a cache, one from a fetch. They look the same. I need to know if they are the same data so I can skip a re-render, avoid a database write, or return a cached result.
The language gives me no way to answer that question. === says no because they are different references. JSON.stringify lies about Date, NaN, and undefined. So I install Lodash, or I write my own buggy version.
That's the problem. Not theoretical. Daily.
Does that land better?
Date is gonna be a tough cookie.
Yeah, Date is tricky. Two Date objects with the same instant should be equal even though they're objects. That's one of the few types where value semantics make sense even without freezing.
But I'm okay with limiting to frozen objects first and seeing if Date needs special handling later. Better to start small and expand than try to solve everything at once.
Aside: JSON.stringify isn't a bad solution just because it wouldn't support certain data types. If the keys of one object are in a different order from another, then they will stringify to different strings and not be considered equal. It really can't be used as a reliable way to handle deep equality checks, even with JSON-serializable data.
Totally. I ran into that exact same thing once β two objects with the same data, just the keys in a different order, and JSON.stringify swore they were different. That was the moment I stopped using it for comparisons.
Like, if you really think about it, {a:1, b:2} and {b:2, a:1} are holding the same information. Order shouldn't matter for an object. It's just one of those things that makes you wish the language had something decent for this.