Can an Array have array indexed accessor properties and other curiosities??
Allen.Wirfs-Brock at microsoft.com
Fri Feb 13 17:23:57 PST 2009
In Mountain View and/or in earlier discussions there was agreement that Array instances needed a special version of [[DefineOwnProperty]] that ensures that the array length invariants are properly maintained in the presence of Object.defineProperty and friends. I'm working on that now and running into several cases that I don't believe have been previously discussed (at least for ES3.1) and have not been adequately address in the special array [[ThrowingPut]].
To start, let's assume that using [[DefineOwnProperty]] to set the value of a property whose name is an array index potentially adjusts the value of the length property, just like [[Put]] did in ES3. Also remember that the length property is born [[Configurable]]: false.
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.
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).
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.
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.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Es-discuss