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

Reply via email to