Determine if a value is Callable/Constructible

Caitlin Potter caitpotter88 at gmail.com
Mon Mar 30 15:25:28 UTC 2015


>>But in either case, these (IsCallable / IsConstructor) are pretty basic qualities of objects that a Reflection* api ought to be able to read into, imho.
>
>What Allen is saying is that the implementation of "throw if constructor" doesn't work by not implementing [[Call]], but rather by implementing [[Call]] to
>throw, so those reflective APIs would say the wrong thing, and that this is observable via proxies.

It’s a fair point, constructors do have a [[Call]] internal method — there’s no reason this needs to be described this way though. Instead of the extra step for classConstructors in 9.2.1, class constructors could just as easily not have a [[Call]] method at all (by default). I guess what I’m getting at is, right now they aren’t “really” callable, it’s just that the way their non-callable-ness is expressed makes them appear callable (which probably should not be the case). Since they’re intrinsically not callable (currently), they shouldn’t be treated as callable.

What Domenic is saying later on makes sense, the magic “call-code” method (should it ever exist) shouldn’t be a property of the class prototype, so a special syntactic form would work better (but also be kind of awful, too).

> 
> Allen, can you say more about why you spec'ed it that way?
>  
> 
> >
> >
> >> 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
> >
> >
> 
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss



More information about the es-discuss mailing list