using Private name objects for declarative property definition.

Allen Wirfs-Brock allen at wirfs-brock.com
Sun Jul 10 10:54:43 PDT 2011


> On Jul 9, 2011, at 7:22 PM, Brendan Eich wrote:
> 
>> On Jul 9, 2011, at 5:02 PM, Allen Wirfs-Brock wrote:
...
>> 1) stratification -  Proxy.isProxy is an example
>> 2) It is impossible or inconvenient to add the classification interface to the appropriate instance interface.  I think that was the reason for Array.isArray.  We were more afraid of adding it to Array.prototype than to Array.
> 
> That's too bad, since we added Function.prototype.isGenerator (which as I noted last time shows up on Function, of course!) without problem. It's Object.prototype that people can't extend, and then the warning about other built-ins is pre-ES5, out of lack of enumerable control, so for fear of breaking for-in loops.
> 
> Adding a non-enumerable Array.prototype method seems doable to me, if the name is clear and not commonly used.


We can probably still add Array.prototoype.isArray if that would help to establish the pattern. Document as being preferred over Array.isArray

> 
>> 
>> Well, if you were actually using Proxy to implement Array, you would probably also be providing the Array implementation.
> 
> Not necessarily -- you might just want isArray to return true for your proxied fakes and the real deal. But yes, you would have to provide at least Array.isArray. With all the standard methods on Array.prototype generic, I believe you wouldn't have to replace all of Array.

but if you want (new Array()) to create the fakes...

> 
>> However, arguably Array.isArray really should have been Array.prototype.isArray.  We treated as a case 2 from above.  May we really didn't need to, but that's water over dam.  I don't think we should use it as precedent for more greenfield situations.
> 
> First thought: Crock sold us on reformed Number.is{NaN,Finite} along with new Numer.isInteger. We can "do both" and correct course for the long run, perhaps: Array.isArray and Array.prototype.isArray. But first we should settle the data property vs. method issue.

yes.  I wonder if isArray and isInteger are different kinds of categorizations ("class" based vs value based) that perhaps should have distinct naming conventions.

>>> 
>> 
>> But f the method implementation is simply going to be return true or return false why do yo need to call it at all?
> 
> The general case is an optional method, a notification hook call-out or some such.
> 
> You're right that for object detection the method call seems a waste. We could have made Function isGenerator a non-writable, non-configurable, and non-enumerable boolean-valued data property.
> 
> But, then it would be an instance property, which burns storage (the shape or hidden class sharing is not the issue, the true or false value slot is); or else an accessor on Function.prototype, which is about as costly as a method in implementations. Users testing it would not have to write (), your point. That wins. But otherwise it's a wash.

Why not a non-writable,non-enumerable non-configurable data property on Function.prototype.

> 
> 
>> Smalltalk code guidelines would general say (but I'll use JS syntax here instead of Smalltalk):
>> 
>> 
>> obj.isFoo    //ok
>> obj.constructor.isFoo(obj)  //less ok, unless there is a good reason
>> Foo.isFoo(obj)   //even less good
>> 
>> In the first two you are only statically coupled to obj
>> in the third you are statically coupled to both obj and Foo.
> 
> Right, and as you say there may be a reason for that (reasons 1 and 3; not sure about 2).
and I should have included:
   obj.constructor === Foo   //very bad 

Allen


More information about the es-discuss mailing list