@@toStringTag spoofing for null and undefined

Tom Van Cutsem tomvc.be at gmail.com
Wed Jan 21 01:10:44 PST 2015

Hi Dave,

> On Tue, Jan 20, 2015 at 4:44 PM, David Ungar <ungar at mac.com> wrote:
>> Self stratifies things into base- and meta- level. The idea is that
>> almost all code is better off sticking to base level because that promotes
>> encapsulation and reuse.
>> At base-level all you can do is throw messages at objects and then throw
>> more messages at whatever bounces off of what the first messages return.
>> So you can always substitute an object with similar behavior for another.
>> At meta-level, you can interrogate the object to look inside; what slots
>> it has, etc.
I subscribe to this design point-of-view (AmbientTalk followed much the
same design, in Self and Smalltalk's footsteps).

I also find your observation about moving identity to the meta-level (and
thus to a more "expert" part of the language) revealing. As long as the
majority of regular application code uses polymorphic equality, you're good.

Ideally, we would have had '==' be an overridable operator, allowing
objects to re-implement identity how they see fit. And we would have had a
more obscure, but unspoofable identity test (in the form of a method call
like Object.is or Object.equals). But alas, that is not JS reality.

The trouble with '===' being our reliable identity test is that it is still
very convenient syntax, so developers will tend to use it even if they
would have been comfortable with a polymorphic, extensible '==' test. And
of course, many in our community have for a long time advocated not using
'==' because it performs implicit conversions.

It's worth comparing JavaScript's situation to Java's: Java has '==' as a
reliable identity test, and it has the equals() method inherited from
java.lang.Object as the polymorphic test. Even in Java though, you often
hear programmers complain about not being able to redefine '==' when they
start to proxy certain objects. My hypothesis is that this is because '=='
is again too convenient syntax, leading developers to over-use it.

Now, coming back to equals(): if only we as a community could agree to a
standard duck-typed method name to perform object equality checks, we
wouldn't need to change the base language at all. We don't need a static
java.lang.Object.equals() method, we can just use duck-typing. The trouble
with that is of course that if the language doesn't choose a standard name,
the community will invent their own. And indeed, many JavaScript libraries
define their own equality operators of sorts (some do double-dispatch, some
do shallow structural comparisons, some do deep-equality, etc.)

So, just like Promises/A+ 'standardised' on 'then' to do promise chaining,
maybe we need to rally around and promote an extensible equality test
implemented as a plain common method. No fancy new syntax or language
extensions required. Of course, we'd still be left with legacy code that
will continue to use '==' and '==='.

> From your response, it sounds as if == is non-overidable today. Is that
>> right?
As Brendan and Mark already pointed out, '==' is indeed non-overridable
today. I'm hopeful that Brendan's value types proposal will amend that in
the future. Barring community consensus on an equals() duck-typed protocol
(which is unlikely to happen), I think that's our best bet in recovering
the benefits of extensible equality tests while keeping nice syntax.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150121/146d789e/attachment.html>

More information about the es-discuss mailing list