Re: Proposal For A New Alternative Keyword To “this” For Classes

Isiah Meadows isiahmeadows at
Wed Mar 13 12:19:49 UTC 2019

Assuming Babel can get ahold of unmodified builtins, even if it's only
during `@babel/runtime` initialization, it could still break that wrapper.
`core-js` itself uses this trick extensively to dodge otherwise observable
side effects in all of its wrappers. 😉

(Babel *might* be invoking `wm.get(this)` and `wm.set(this)`, but it should
really be binding those on initialization where possible.)
On Tue, Mar 12, 2019 at 14:36 Ranando King <kingmph at> wrote:

> @Isiah Remember, the class-fields proposal has absorbed the private-fields
> proposal, and it is those private fields that have no precise equivalent.
> WeakMap and closures can approximate what private fields do. However,
> private fields has semantics and capabilities that cannot be fully
> reproduced in current ES. For instance, I can wrap both WeakMap and Proxy
> in a way that Babel private-fields will be proxy safe. With native private
> fields, that's impossible.
> On Tue, Mar 12, 2019 at 10:39 AM Isiah Meadows <isiahmeadows at>
> wrote:
>> @Ranando Minor nit: class fields can be purely implemented in terms of
>> `defineProperty` (for public) and weak maps (for private - what's used
>> today for private data). Private methods could be implemented in terms of
>> weak sets/maps and an object with methods outside the class's scope.
>> Private static properties could just verify `this === Type`.
>> So no, those don't quite reify classes, either. (If something can be
>> fully transpiled or polyfilled, it doesn't create or reify any new
>> primitives.)
>> On Tue, Mar 12, 2019 at 09:51 Ranando King <kingmph at> wrote:
>>> I get what you're after. I touched on the same things when creating my
>>> private members proposal. The best of approaches for what you want is
>>> indeed relying on the lexical scope to act as a binding for all class
>>> members. There's just a couple of problems with doing things that way:
>>> 1. ES is a dynamic language. This makes lexical binding difficult
>>> because it's entirely possible to call a non-static class method where
>>> *this* is undefined or null. Not allowing for that scenario will break
>>> existing code. Allowing for that scenario will cause variables to be
>>> unexpectedly either written to the global scope or throw.
>>> 2. Class isn't really a "thing" in ES, at least, it isn't until
>>> class-fields lands. The use of the *class* keyword is currently
>>> completely optional. There's nothing in current ES that you can do with
>>> *class* that can't be done without it except use the *super()* call in
>>> the constructor function. But even that can be substituted with
>>> *Reflect.construct*(). Class-fields will destroy this symmetry, making
>>> *class* it's own unique "thing". But until then, what do you do about
>>> all the "classes" that don't use the *class* keyword?
>>> Long and short, this means both the lexical scope approach and the
>>> alternate keyword approach will either break existing code or bring
>>> dubious-to-no benefit.
>>> On Tue, Mar 12, 2019 at 3:06 AM john larson <johnlarsondev1 at>
>>> wrote:
>>>> So in terms of implementation, may be having instance method/property
>>>> references on the objects and having static method/property references on
>>>> the prototype is the solution?
>>>> On Tue, Mar 12, 2019 at 8:14 AM Isiah Meadows <isiahmeadows at>
>>>> wrote:
>>>>> I've done a little engine work, and inline caches work by inline type
>>>>> maps based on the callee site. This *can* be used to reconstruct values +
>>>>> receivers, but only when the value is constant. It is not sufficient to
>>>>> ensure identity remains the same, and engines would still need a weak map
>>>>> to link methods to instances (as opposed to prototypes).
>>>>> It's worth noting not even Java or Ruby offers this - their method
>>>>> references/objects (like our bound functions) are *not* memoized - they're
>>>>> linked to classes, not instances. Python is the exception here in
>>>>> auto-binding instance methods, not the norm.
>>>>> On Mon, Mar 11, 2019 at 15:37 Bergi <a.d.bergi at> wrote:
>>>>>> Hi John!
>>>>>> > I think the js run-time already has that information at hand, so as
>>>>>> > long as we don't implement this as pure syntactical sugar, there
>>>>>> would
>>>>>> > not be a need to keep an extra reference to anything, because it
>>>>>> would
>>>>>> > be already there. The run-time will know which instance the invoked
>>>>>> > method belongs to.
>>>>>> Well no, you're wrong here: the runtime does not have this information
>>>>>> at hand. In your example (simplified)
>>>>>> ```
>>>>>> var reqManager = new RequestManager();
>>>>>> function addEventListener(f) {
>>>>>>      console.log(f);
>>>>>>      f(event);
>>>>>> }
>>>>>> addEventListener(reqManager.responseHandler);
>>>>>> ```
>>>>>> the `addEventListener` function will not know that the function `f`
>>>>>> you
>>>>>> passed was a method of the `reqManager` instance. It cannot
>>>>>> distinguish
>>>>>> that call from
>>>>>> ```
>>>>>> addEventListener(RequestManager.prototype.responseHandler);
>>>>>> ```
>>>>>> or
>>>>>> ```
>>>>>> var g = otherReqManager.responseHandler;
>>>>>> addEventListener(g);
>>>>>> ```
>>>>>> It is exactly the same function that is passed in all three cases.
>>>>>> There
>>>>>> is no instance bound to `f`, and `f(event)` will not invoke it as a
>>>>>> method (with a receiver/`this` value).
>>>>>> Best regards,
>>>>>>   Bergi
>>>>>> _______________________________________________
>>>>>> es-discuss mailing list
>>>>>> es-discuss at
>>>>> _______________________________________________
>>>>> es-discuss mailing list
>>>>> es-discuss at
>>>> _______________________________________________
>>>> es-discuss mailing list
>>>> es-discuss at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list