Can an Array have array indexed accessor properties and other curiosities??
Mark S. Miller
erights at google.com
Sun Feb 15 10:23:29 PST 2009
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.
#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
> 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
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
* 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