IsConstructor

Allen Wirfs-Brock allen at wirfs-brock.com
Thu Jun 12 08:26:23 PDT 2014


On Jun 12, 2014, at 8:06 AM, Domenic Denicola wrote:

> 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.

There's a lot of subtle stuff going on with these compatibility cases and addressing them was something we needed to do to get consensus around supporting subclassing of Array. I don't think we want to mess them up simply to avoid spec. level use of IsConstructor.  I really don't expect anybody to seriously try to self-host the compatibility aspects of those methods and there is little point in trying to do a ES5 level shim that includes  that functionality because other aspects of of subclassing just won't work in ES5.

Allen





> 
> ________________________________________
> From: Allen Wirfs-Brock <allen at wirfs-brock.com>
> 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 wirfs-brock.com> 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};
> arraybuilder.of(1,2,3,4);
> 
> 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:
> 
> Functiuon.isCallable(value)
> Function.isConstructor(value)  //or maybe it should be Function.isNewable ?
> 
> Allen
> 
> 



More information about the es-discuss mailing list