Determine if a value is Callable/Constructible

Allen Wirfs-Brock allen at wirfs-brock.com
Mon Mar 30 05:49:43 UTC 2015


> On Mar 29, 2015, at 11:51 PM, Caitlin Potter <caitpotter88 at gmail.com> wrote:
> 
> ...
> 
> Reflect.isConstructor(fn) -> true if Class constructor, generator, or legacy (and non-builtin) function syntactic form
> Reflect.isCallable(fn) -> true for pretty much any function, except for class constructors and a few builtins

I’ve already seen another situation (node’s Buffer) where code could be simplified by using a ES6 class definition but where that is prevented because a class constructor throws when called.

Just to clarify something.  Class constructors actually are “callable”.  You can observe this by the fact that Proxy allows you to install an “apply” handler (the reification of the [[[Call]] internal method) on a class constructor.   The the fact that an object can be [[Call]]’ed is already reflected  by the typeof operator.  Class constructors throw when called because at the last minute we choose to make their [[Call]] do an explicit throw not because they aren’t callable.

There is no intrinsic reason why we needed to mandate that class constructors should throw when called.  We even provided a simple and straight forward way (new.target===undefined) that a ES constructor body can use to determine whether it was called or new’ed.  

I think we should just drop that throws when called feature of class constructors..

(The restriction was added to future proof for the possibility of inventing some other way to provide a class with distinct new/call behavior. I don’t think we need nor can afford to wait for the invention of a new mechanism which will inevitably be more complex than new.target, which we already have.)

Allen




More information about the es-discuss mailing list