What is an array?

David Bruant david.bruant at labri.fr
Wed Mar 30 03:30:10 PDT 2011


I have recently read
and in particular "Array.isArray should test for presence of special
[[DefineOwnProperty]] rather than testing [[Class]" (There is a typo, by
the way) which has woken up one fundamental question which is "what is
an array?". The consequence of this is "for what Array.isArray should
return true or false?"

Starting with the defintion of "new Array" in the ES5 spec, we can see
that an Array is created with a certain prototype value and the internal
[[Class]] equal to "Array".
Of course, the prototype doesn't define an Array by itself.
Object.create(Array.prototype) will not return what we could consider as
an Array. In a way, same thing for [[Class]], it's "just a string" and
doesn't really identify what arrays are.
One thing that caracterizes arrays is the internal connexion between
"length" and numerical properties. This link can be found in the
specific [[DefineOwnProperty]]. But I think it may be too quick to
conclude that Arrays are the objects with this particular internal
function. One could imagine that one day, other objects have this
particular [[DefineOwnProperty]] internal methods, but other [[Get]] or
[[Set]] or [[HasProperty]] internal methods. In my opinion, one thing
that makes an Array what it is is all internal methods and the internal
consistency they create altogether. It turns out they are all the same
than the Object ones and only [[DefineOwnProperty]] is different, but
still, the internal consistency we rely on when using Arrays exists
because of the conjunction of all internal properties.
But recently, I have created the ProxyArray library
(https://github.com/DavidBruant/ProxyArray) where, on a proxy, I have
recreated the internal array behavior and special relationship between
'length' and numerical indices. Leaving aside the fact that no ES engine
could determine whether a proxy handler has the exact same semantics
than actual array internal methods, my library doesn't create Arrays
anyway. One of the reason is that, for instance, even if the engine
could tell that the semantics is the same, it would certainly not apply
Array-specific optimizations.

I have mentionned "Array-specific optimizations". The same way, in the
spec, for most Array.prototype method is written something like "The
filter function is intentionally generic; it does not require that its
this value be an Array object.". In these two contexts, what does
"Array" mean?
My answer to this last question and my (partial) conclusion to the
discussion is:
"An array is something created after a 'new Array()' call (where 'Array'
is the built-in constructor define in the spec). "
As a consequence, it englobes things created after a call to "Array()"
(ES5 - Create and return a new Array object exactly as if the
standard built-in constructor Array was used in a new expression with
the same arguments (15.4.2).) or array literals (ES5 11.1.4 Array
Initialiser - semantics Step 1 of "ArrayLiteral : [ Elisionopt ]" and
"ElementList : Elisionopt AssignmentExpression").

In my opinion, at creation (direct or indirect "new Array()"), arrays
should internally contain a marker saying they've being created with the
built-in Array constructor. I think that the intention behind [[Class]]
was to have such a marker. But in a way, it's "just a string" and we
could imagine a world where the [[Class]] was settable on some objects.
Nevertheless even if setting [[Class]] to arrays it wouldn't make them
Arrays just because some string has the right value.

Earlier, I said that it was a partial conclusion. I would like to
addArray subclassesto the definition. The "Standardizing __proto__"
thread led to the idea of standardizing a subclassing mechanism. In my
opinion, objects constructed as subclassed arrays should benefit from
the Array identity (return true to "Array.isArray") and as a consequence
benefit from Array extras natively (in ES5, applying Array extras to
non-Array objects is implementation-specific).

Of course, all of this is just my opinion and is open to debate.


Influencial readings :
- ES5 new Array (http://es5.github.com/#x15.4.2.1)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110330/55f7f395/attachment-0001.html>

More information about the es-discuss mailing list