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.
Opinions?
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.
_______________________________________________
Es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss