On Feb 15, 2009, at 10:23 AM, Mark S. Miller wrote:
2009/2/13 Allen Wirfs-Brock <[email protected]>:
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
_______________________________________________
Es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss