Can an Array have array indexed accessor properties and other curiosities??

Brendan Eich brendan at mozilla.com
Sun Feb 15 10:43:29 PST 2009


On Feb 15, 2009, at 10:23 AM, Mark S. Miller wrote:

> 2009/2/13 Allen Wirfs-Brock <Allen.Wirfs-Brock at microsoft.com>:
>>
>> What happens, if the [[DefineOwnProperty]] is used to create an  
>> accessor
>> property of an array instance whose name is an array index.  I've  
>> thought of
>> three possibilities:
>>
>> 1) It's disallowed, Array instances can't have own accessor  
>> properties with
>> array index names. (and since Array.prototype is an Array instance  
>> it can't
>> either. An array instance could only inherit an accessor property  
>> with an
>> array index name from Object.prototype)
>>
>> 2) It's allowed, but defining such a property doesn't cause length  
>> to change
>> (when the array index name is >= the current length) and explicitly  
>> reducing
>> the length does not delete such properties.
>>
>> 3) They are treated just like data properties WRT the length  
>> invariant.
>>
>> My preference is #1.  Accessor properties are new to the standard  
>> and we get
>> to decide where they are and aren't allowed.  Excluding them from  
>> indexed
>> array properties eliminates some complicating edge cases and may  
>> place less
>> of a burden on implementations that want to optimized array  
>> representations.
>> However, it may (??) impact existing implementation that already have
>> arrays that allow getter/setter methods.
>
> My preference is #3, closely followed by #1. If implementation or
> legacy constraints would favor #1, that's fine.

Implementations want 3, so do users. SpiderMonkey js shell sessions:

js> a = [1,2,3]
1,2,3
js> a.__defineGetter__(9, function()42)
js> a.length
10
js>
Yoyodyne:src brendaneich$ ./Darwin_DBG.OBJ/js
js> a = [0,1,2]
0,1,2
js> a.length
3
js> a.__defineGetter__(9, function(){return 9})
js> a.length
10
js> a
0,1,2,,,,,,,9


> #2 just seems weird and irregular to me. I am against it. #2 would
> mean that -- even without using the new Object meta methods --
> accessor properties become less transparent virtualizations of data
> properties. It also loses the invariant that you mention below: that
> "length is > than the name of any array indexed own properties."

Agreed.


> Even #3 does not enable the creation of array P that acts as a
> transparent proxy for array Q, where P and Q are genuine arrays, since
> there's no way for P's length to track changes to Q's length. So I see
> no strong argument for #3 over #1.

Existing practice favors 3 over 1. That's decisive in my opinion  
(getters and setters are a de-facto standard ES3.1 is codifying and  
improving).


> 3) Delete from the end until we can't
> * length is set to max(1+largest array index of a non-configurable
> property, attemptedNewLength).
> * all array indexed properties >= new value of length are deleted
> * if the new value of length != attemptedNewLength, then throw.
>
> This #3 has the problem that it is not failure atomic: on failure, it
> has partially changed the array. But it does preserve the invariant.


(Plea for A/B/C after different 1/2/3 numbered list style!)

So (reading ahead one message) I join Mark in agreeing with Breton's  
followup proposal, or amendment to the second #1 (if you know what I  
mean! :-P).

/be


More information about the Es-discuss mailing list