Determine if a value is Callable/Constructible

Caitlin Potter caitpotter88 at
Mon Mar 30 15:38:03 UTC 2015

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

s/Object (implements [[Call]]) |	“function” /Object (implements [[Call]] or [[FunctionKind]] is classConstructor) |	“function”/g

Problem solved!

I jest — but making a constructor identifiable as a function while still noting that it’s not “really” callable is certainly possible

> On Mar 30, 2015, at 11:27 AM, Domenic Denicola <d at> wrote:
> 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] On Behalf Of
>> Caitlin Potter
>> Sent: Monday, March 30, 2015 11:25
>> To: Yehuda Katz
>> Cc: es-discuss at
>> 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>
>> 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 ( 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, which we already have.)
>>>> Allen
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at

More information about the es-discuss mailing list