Accesssing ES6 class constructor function

Tiddo Langerak tiddolangerak at gmail.com
Thu Jan 5 18:04:09 UTC 2017


I don't think it is possible to call the constructor as a function. 
However, in JavaScript a class is just an object (unlike C# or Java, 
where it's meta data), which means that you can pass it around and 
dynamically extend it. E.g. you can intercept class creation like this:

function enhanceClass(c) {
     return class EnhancedClass extends c {
         constructor() {
             //do your magic here
         }
     }
}

class MyClass {}

const EnhancedMyClass = enhanceClass(MyClass);
new EnhancedMyClass();

As for `toString` & not being able to call a function directly: 
`toString` is already overwriteable, and in ES5 code it wasn't uncommon 
to throw from a constructor if it wasn't called as one (for good 
reasons). ES6 classes just do that for you.

On 01/05/2017 06:31 PM, James Treworgy wrote:
> Hi - I am brand new to this list, I find myself here because of a 
> confounding issue related to ES6 classes vs. traditional constructors. 
> Forgive me if this is something that's been hashed out in times past. 
> I looked around for discussion online and couldn't find anything more 
> than the observation that the spec prohibits invoking it - not really 
> any discussion. Probably a failing of google more than anything else, 
> so if there's some discussion that I should read to catch up please 
> point me there.
>
> Here's my issue. The ES6 spec prohibits invoking class constructors 
> without "new". This makes such functions a special case, e.g.
>
> class Test() {}
>
> // typeof Test === 'function'  // yep
> // Test.prototype.constructor === Test // yep
>
> // Test() => nope ... TypeError: Class constructor Test cannot be 
> invoked without 'new'
> // Test.call() ... nope
> // Test.apply() ... nope
>
> This has some interesting consequences. It means testing something for 
> typeof "function" no longer guarantees it can be invoked without 
> error. Also "function.toString()" can now return something that isn't 
> actually a legal function definiton (since it returns the whole class 
> as text). There seems to be no method, through various javascript 
> reflection/invocation techniques or otherwise, to invoke a class 
> constructor except by creating an instance of the class.
>
> For tool-builders the consequences of this are significant. It's no 
> longer possible to create something that can extend/wrap/act on a 
> prototype by intercepting it's construction process, as it was before 
> with plain ES5 constructors. So classes are fundamentally different 
> than prototype contructors in how we can use them, far more than 
> syntactic sugar. This has come into play lately for me, as an DI 
> container we use that does exactly this doesn't work with ES6 classes 
> (and as far as I can tell, there's no way to make it work, other than 
> having devs no longer use class syntax).
>
> This seems a strange design decision. Even conventional OO languages 
> like C# have the capability to reflect on classes and access the 
> constructor directly as a function. It seems to fly in the face of the 
> basic openness/dyanamic nature of JavaScript, and more signficantly, 
> creates a kind of backward incompatibility since a function is no 
> longer just a function.
>
> I'm wondering whether I'm missing some mechanism for legally accessing 
> a class constructor as a function (other than parsing the output of 
> toString() and eval!) -- and generally thoughts on this aspect of the 
> ES6 specification.
>
> Thank you!
>
>
>
> _______________________________________________
> 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/a729badc/attachment.html>


More information about the es-discuss mailing list