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

Isiah Meadows isiahmeadows at
Tue Mar 12 15:39:47 UTC 2019

@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