Accesssing ES6 class constructor function

James Treworgy jamietre at gmail.com
Thu Jan 5 22:10:47 UTC 2017


> At which point you've lost your logger, right?

That's up to the constructor that got passed in - the only job of
"createInstance" is to make sure that the client constructor has the
dependencies available to it in some way, ideally one that doesn't require
writing boilerplate in every class. If a constructor chooses to return
something other than it's own instance, I don't really care whether or not
it exposes logger, because those dependencies are only for its own use
anyway.

The actual pattern might not be to assign the deps to a public property
anyway, it could be assign them all to `this[_someSymbol]` or whatever. The
only goal is to make them already available to it, in whatever convention
we choose in the app, without having to pollute the actual constructor with
a "deps" argument and boilerplate to assign them in every class.

So I get that this decision has to do with making builtins extensible, but
I don't totally understand why it has to apply to everything, or even why
we can't just allow people mis-using the builtin constructors to have
strange behavior, as we do with Array in ES5.

That is, if I was simply allowed to access "Cotr" as a function, why would
anything else cease to work? We remove some risk of abuse, but seems a bit
like we threw the baby out with the bathwater. We could still have the
class syntax work the same way, but not prevent people from accessing their
own constructor functions.

I mean, nothing's stopping me writing classes like this:


class Thing {
    constructor(...args) {
        Thing.cotr.call(this, ...args)
    }
}

Thing.cotr = function() { ... }


Now I have access to my constructor function. I could just write a babel
plugin to convert all my classes to this syntax :) But it all seems so
unnecessary







On Thu, Jan 5, 2017 at 4:56 PM, Boris Zbarsky <bzbarsky at mit.edu> wrote:

> On 1/5/17 2:21 PM, James Treworgy wrote:
>
>> function createInstance(Cotr, args /* array */) {
>>     function F() {
>>        // this is dynamic in reality but simple example of injecting
>> something...
>>        this.logger = new Logger();
>>
>>        var instance = Cotr.apply(this, args)
>>
>
> So the thing is...
>
> This works for script-defined constructors.  But it never worked right for
> constructors of built-ins.
>
>        return instance; // in case Cotr returns something
>>
>
> At which point you've lost your logger, right?
>
> Specifically, in the ES5 world, if the Cotr that's passed in there is
> Array or Date, say, then instance != this and you don't get the logger
> thing.
>
> The behavior of ES6 constructors is meant to be able to explain the
> construction of such built-ins (and especially the new ones like Map, as
> well as the various DOM built-ins in browsers) _and_ to allow subclassing
> such built-ins usefully.
>
>
> So the Cotr can refer to "this.logger" in the constructor. I don't think
>> there's a way to do this with dynamic class inheritance since you always
>> have to call super() before you can assign any properties in a
>> constructor.
>>
>
> That's unavoidable if you want to allow Cotr to control the actual object
> allocation, which was one of the design constraints here to enable
> built-ins to work the same way as non-built-ins.
>
> -Boris
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170105/c9737790/attachment.html>


More information about the es-discuss mailing list