Object.isEqual
Steve Fink
sphink at gmail.com
Mon May 1 23:28:56 UTC 2017
On 05/01/2017 03:15 PM, Alexander Jones wrote:
> No I was not proposing that it actually *be* stringified-comparison...
> or in any way be related to the JSON global.
>
> * Property order would not be important for equality. Precedent is set
> by common sense.
> * Reference semantics (i.e. visitation) would be exactly as you'd
> expect - look at Python's `dict` implementation for IMO the only
> obvious answer.
> * I acknowledged specifically that JSON does not support all types,
> just use SameValueZero for primitives and be done with it.
> * Cycles are a subset of all possible reference semantics.
> * Getters should be called. It already works for JSON and I don't hear
> anyone complaining about it. (Maybe I wasn't listening?) - same for
> prototype chain questions...
If there is any possibility that anything has a getter, anywhere in the
tree you're comparing, then you will have to do a full tree traversal.
Even if you're comparing an object to itself. Both
isEqual({'foo': giantHugeObject}, {'foo': giantHugeObject});
and
isEqual(giantHugeObject, giantHugeObject);
have to traverse through giantHugeObject in order to find any getters to
invoke, which will be far slower than a simple JS function that
short-circuits if things are ===. But then what's the point?
Arguably, an engine could *know* that neither of the objects has any
nontrivially-comparable children, but that requires fancy type tracking
(eg if someone does a setPrototypeOf, you'd better be able to find
everything affected and invalidate that compares-fast bit.)
As you point out, Maps are simpler. Map keys can't have getters (though
I guess a Proxy of a Map could?). Maybe there's more hope for a Map.isEqual?
>
> That said, most of these questions evaporate if people would just
> start using Map for things. AFAIAC the main reason people don't is due
> to the absence of a Map literal and JSON parsing tending to give you
> Object back instead of a more appropriate type without such weirdness
> as prototypes and property descriptors (yes, I went there!).
>
>
>
> On 1 May 2017 at 22:55, Steve Fink <sphink at gmail.com
> <mailto:sphink at gmail.com>> wrote:
>
> It would be nice to have *something* for this. Some remaining
> problems I see with using JSON serialization, let's call it
> JSON.isEqual:
> - JS has order, JSON does not
> - JSON lacks NaN, +/-Infinity (and JSON.stringify maps these to
> null, which means JSON.isEqual({x: 0/0}, {x: 1/0}))
> - cycles
> - ...and everything under your "trivial generalisation"
>
> It still seems like it'd be unfortunate if !JSON.isEqual({foo:
> val1}, {foo: val2}) where val1 === val2 (because val1/2 is not
> serializable, eg it has a cycle).
>
>
> Also, what is
>
> var x = 4;
> JSON.isEqual({get foo() { return x++; }}, {foo: 4})
>
> ? If you went purely by "whatever JSON.stringify would return",
> then this would be true once and false afterwards.
>
> This may seem like nitpicking, but if you don't nail down the
> exact semantics, then engines will end up doing the JSON
> serialization and a string compare, which rather defeats the
> purpose. If you stick to something simple like comparing
> JSON.stringify output, then they will pretty much *have* to do
> this, since there are so many observable side effects like getter
> invocation and proxy traps. You *could* define semantics that
> cover a large percentage of the interesting cases, but JSON isn't
> going to be of much help.
>
> And for the record, JSON does not have an intuitive semantics at
> all. It has intuitive semantics for a small subset of values, a
> subset that is rarely adhered to except near interchange points
> where JSON makes sense. (And even then, it's common to
> accidentally step outside of it, for example by having something
> overflow to Infinity or accidentally produce a NaN.)
>
> On 05/01/2017 02:04 PM, Alexander Jones wrote:
>> I hear this argument a lot but it strikes me with cognitive
>> dissonance! JSON defines a very intuitive notion of object
>> value-semantics - whether the serialized JSON is an equivalent
>> string. Granted that many value types are not supported by JSON,
>> but it's a trivial generalisation.
>>
>> Let's just give the above a name and get on with it. For 99% of
>> use cases it would be ideal, no?
>>
>> Thoughts?
>>
>> On 1 May 2017 at 20:58, Oriol _ <oriol-bugzilla at hotmail.com
>> <mailto:oriol-bugzilla at hotmail.com>> wrote:
>>
>> This is not easy to generalize. Comparing objects is one
>> thing lots of people want, but not everybody needs the same
>> kind of comparison.
>> For example, you compare own property strings. But what about
>> symbols? Somebody might consider two objects to be different
>> if they have different symbol properties.
>> Or the opposite, somebody may think that checking enumerable
>> properties is enough, and non-enumerable ones can be skipped.
>> Then some property values might be objects. Are they compared
>> with === or recursively with this algorithm (be aware of cycles)?
>> Similarly, for the [[Prototype]]. Do inherited properties
>> matter? Should [[Prototype]]s be compared with === or
>> recursively?
>> There is also the problem of getters: each time you read a
>> property, it might give a different value! You might want to
>> get the property descriptor and compare the values or the
>> getter functions.
>> And then there are proxies. Taking them into account, I don't
>> think there is any reasonable way to compare objects.
>>
>> So I think it's better if each person writes the code that
>> compares objects according to their needs.
>>
>> --Oriol
>>
>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
> https://mail.mozilla.org/listinfo/es-discuss
> <https://mail.mozilla.org/listinfo/es-discuss>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170501/f0c010aa/attachment.html>
More information about the es-discuss
mailing list