Thomas said:
Lasse said:
Thomas 'PointedEars' Lahn wrote:
Since in "[0, , 2]", the second "comma in the element
list is not preceded by an AssignmentExpression", to be
exact, is "a comma [...] after another comma", "the
missing array element ..." [continue reading above]. And
so:
| 7. Return Result(1)
=> [0, undefined, 2]
No, return the array created in line 1. of the rule for
"ElementList : Elision_opt AssignmentExpression", which
has since been modified by calls to [[Put]](0,0) and
[[Put]](2,2). It has no property called "1".
You suggest it to have a length (number of elements) of 3
but do not have a second element. That's ridiculous.
Maybe that is a consequence of reading the algorithm for the Object's
[[Put]] method where the algorithm for the Array [[Put]] method really
applies to the process:-
<quote cite="ECMA 262 3rd edition Section 15.4.5.1">
15.4.5.1 [[Put]] (P, V)
Array objects use a variation of the [[Put]] method used
for other native ECMAScript objects (section 8.6.2.2).
Assume A is an Array object and P is a string.
When the [[Put]] method of A is called with property P
and value V, the following steps are taken:
1. Call the [[CanPut]] method of A with name P.
2. If Result(1) is false, return.
3. If A doesn't have a property with name P, go to step 7.
4. If P is "length", go to step 12.
5. Set the value of property P of A to V.
6. Go to step 8.
7. Create a property with name P, set its value to V and
give it empty attributes.
8. If P is not an array index, return.
9. If ToUint32(P) is less than the value of the length
property of A, then return.
10. Change (or set) the value of the length property of A
to ToUint32(P)+1.
11. Return.
12. Compute ToUint32(V).
13. If Result(12) is not equal to ToNumber(V), throw a
RangeError exception.
14. For every integer k that is less than the value of the
length property of A but not less than Result(12), if A
itself has a property (not an inherited property) named
ToString(k), then delete that property.
15. Set the value of property P of A to Result(12).
16. Return.
</quote>
Which needs to be suplimented with the defenition of "array index"
provided at the beginning of section 15.4:-
<quote cite="ECMA 262 3rd edition section 15.4">
A property name P (in the form of a string value) is an array
index if and only if ToString(ToUint32(P)) is equal to P and
ToUint32(P) is not equal to [1] 2<sup>32</sup> -1.
</quote>
[1: two to the power of 32, minus one]
So given the code:-
var a = new Array();
a[100] = 1;
- the resulting array object resembles:-
{
'100':1,
'length':101
}
- because the property name qualifies as an "array index" and the
[[Put]] algorithm assigns a value to the Array's - length - property
that is one greater than the numeric equivalent of the property name.
The `in' operation returns `true' if/while the second
operand has a property named as the first operand; since
that property ("1") exists here, it returns `true'.
(The property's value does not matter, as you just explained.)
Except that it doesn't exist, because no call to [[Put]] have
been made with a first argument of 1.
Does not matter. As a specialty of Array objects which are
defined to be dynamic, there should be (and is in JavaScript)
a property named "1" created (unless you want to complicate
usage).
All objects ECMAScript, including arrays, are augmented instances of the
native ECMAScript object, which supports the dynamic adding of named
properties at runtime.
The augmentations that apply to the Array objects are that an
alternative [[Put]] method is used, and the constructor adds a -
length - property and initialises it to zero. And that, combined with
the normal behaviour of the Object's [[Get]] method (returning -
undefined - when an object does not have a property with the requested
name), is all that is necessary to turn a dynamic object into a dynamic
sparse Array implementation.
These three details provide the array-ness of an Array, end explain why
array-ness has nothing to do with the use of an Object as a "hashtable"
or "associative array".
ECMAScript simply does not need to create a property with the name "1"
and the value - undefined - for the Array literal - [ 0, , 2 ] -
because reading a property with that name will return - undefined -
whenever the property does not exist.
And there is a great deal to be said for a dynamic spars array
implementation not creating actual named properties for all 'elements'
in an Array. Consider:-
var a = new Array();
a[4294967295] = 0;
If all the named properties were created on the Array object the result
would resemble:-
{
'0':undefined,
'1':undefined,
...
'4294967294':undefined,
'4294967295':0,
'length':4294967296
}
- and probably exceed the entire memory map in 32 bit operating system.
While;-
{
'4294967295':0,
'length':4294967296
}
- is a trivial object.
In terms of the normal use of an Array there would be no difference
(assuming the resources where available to accommodate the first, and
disregarding the performance differences in property resolution).
It is clearly not a good idea to add named properties to an Array to
fill in gaps when an element is created with a large 'array index' . So
the Array should be able to accommodate having many fewer actual
properties than its - length - property might imply. And under those
circumstances there is no reason to expect special behaviour form the
creation of an Array using an Array literal.
... . ECMAScript does not explicitely forbid the "1"
property to be created implicitely. And as Richard
recently pointed out,
| [...] a conforming implementation of ECMAScript is
| permitted to provide properties not described in this
| specification [...]
|
| A conforming implementation of ECMAScript is permitted
| to support program [...] syntax not described in this
| specification.
AIUI, that includes creating properties/elements with
value `undefined' implicitely for Array objects if they
are elided in an Array initialiser.
The conformance section has two 'Must' paragraphs followed by two 'May'
(expressed as "is permitted to") paragraphs. While the algorithms that
define the semantics certainly do not result in the creation of a
property named "1" it might be argued that freedom to provide additional
properties provided by the 'May' paragraphs could accommodated its
creation during the process.
It might also be argued that where an algorithm for a process describes
the changes made to an object during that process the changes made to
that object should not exceed those stated in the algorithm (at least to
the extent that those changes are publicly determinable).
It makes perfect sense to me that the language should allow for
additional named properties of an array that apply to all Array objects
from their creation. But adding a property to an object during a
specified process seems to require additional steps in the applicable
algorithms, and additional steps in an algorithm means that it is a
different algorithm, and so does not conform to ECMA 262.
Richard.