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

Mark S. Miller erights at
Sun Feb 15 10:23:29 PST 2009

2009/2/13 Allen Wirfs-Brock <Allen.Wirfs-Brock at>:
> 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.

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

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.

> Here's another one.  What happens if the length field is set [[Writable]]:
> false  and an attempt is subsequently make to define an array indexed
> property (using either [[Put]] or Object.defineProperty) whose name is >=
> than length?  I suggest  it fails (silently or not depending upon the Throw
> parameter).

I agree.

> What happens if the length is explicitly reduced such that an array indexed
> property that is [[Configurable]]: false would be deleted by the ES3  array
> [[Put]] algorithm? Alternatives:
>                1) The undeletable property is left undisturbed.  (This
> tosses out the ES3 invariant that length is > than the name of any array
> indexed own properties.
>                2) The redefinition of length fails (silently or not
> depending upon the Throw parameter).
> My preference is #1.  #2 might be more consistent with my read-only length
> recommendation but I'm concern that it requires implementations to use a two
> pass algorithm to ensure atomicity.  I'd prefer that not to impose that on
> implementers.

As mentioned above, I think we should not lose that invariant, so I am
against choice #1. Absent possible implementation constraints, I like
choice #2. However, to avoid the two-phase issue, how about

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.

> In summary, because accessor properties and program controllable attribute
> values are new in ES3.1 we have some flexibility in specifying these
> behaviors.  I think we should choose the alternatives that avoids adding to
> the semantic complexity of arrays and minimizes implementation complexity.



More information about the Es-discuss mailing list