Determine if a value is Callable/Constructible

Domenic Denicola d at domenic.me
Mon Mar 30 15:27:52 UTC 2015


If you made them non-callable by not implementing [[Call]], then typeof would no longer return "function", which would be ... O_o.

> -----Original Message-----
> From: es-discuss [mailto:es-discuss-bounces at mozilla.org] On Behalf Of
> Caitlin Potter
> Sent: Monday, March 30, 2015 11:25
> To: Yehuda Katz
> Cc: es-discuss at mozilla.org
> Subject: Re: Determine if a value is Callable/Constructible
> 
> >>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
> 
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss


More information about the es-discuss mailing list