Domenic Denicola domenic at
Thu Jun 12 08:06:23 PDT 2014

I'd be most interested in seeing if we can remove IsConstructor entirely (except for uses where it's just a guard, implementing the semantics of `new` via IsConstructor -> [[Construct]] or throw).

It seems like there's at least some movement toward removing it from `Array.of` and `Array.from`. All that remains is its use to preserve the `arrayInstance.constructor = undefined` backward-compatibility possibilities. My preference would be to see if we can get away with breaking that use case, and reintroduce it if that turns out not to be web-compatible.

From: Allen Wirfs-Brock <allen at>
Sent: Thursday, June 12, 2014 10:59
To: Jason Orendorff
Cc: Domenic Denicola; EcmaScript
Subject: Re: IsConstructor

On Jun 12, 2014, at 5:36 AM, Jason Orendorff wrote:

> On Wed, Jun 11, 2014 at 11:44 AM, Allen Wirfs-Brock
> <allen at> wrote:
>> Array.from and Array.of have a non-throwing IsConstrutor test because they are designed to allow things like this:
>> let of = Array.of;
>> of(1,2,3,4,5);   //Equivalent to: Array.of(1,2,3,4,5)
>> I don't recall why we provided that functionality.  It doesn't seem to me like a pattern we should want to encourage.
> I think it was meant for functional programming; but FP is so poorly
> supported by the rest of the standard library that it's not useful by
> itself.
> Array.of could test 'if the this value is undefined' rather than using
> IsConstructor(). I like that. I can't put my finger on it, but I
> suspect people will try to treat Array.of as a standalone function and
> get the "undefined is not a constructor" error, and be baffled.

The problem with the undefined test is that it doesn't work if somebody tries to attach such functions to a namespace object:

let arraybuilder = {of: Array.of, from: array:Array.from};

or consider, at the global level:
var of = Array.of;
of(1,2,3); //works
this.of(1,2,3) //breaks

That's essentially why we have the IsConstructor test.  To distinguish between this values that are actual constructors that will be used to create the new collection and non-constructor objects that are just contains for the function.

> Back to the topic, it seems weird to go out of our way to expose
> @@isRegExp and @@isConcatSpreadable and also go out of our way to hide
> IsConstructor(). I don't like "does this object conform to this
> protocol" tests, but they are a fact of life in real JS code.

I think the @@is methods and isConstructor are different kinds of beasts.  isConstructor wold be a very general predicate that queries a fundamental characteristic of the meta-object protocol.  The @@is methods are local to the implementation of a specific abstraction and nobody really needs to know about them unless they are trying to extend that abstraction.

I'm not really opposed to an isConstructor predicate, I'm just pushing back to see if it is something that really needs to be exposed.  If we have it, I think we probably should also have a isCallable predicate and I'd hand both of them off of Function.  IE:

Function.isConstructor(value)  //or maybe it should be Function.isNewable ?


More information about the es-discuss mailing list