Object is not very big. In fact it seems
Array mainly adds the
length field, so you can use both
Objects as numeric arrays:
var ar = new Array(); ar = "foo"; ar["bar"] = "foo"; var ob = new Object(); ob = "foo"; ob["bar"] = "foo"; assert(ar == ob == ar["0"] == ob["0"] == ar.bar == ob.bar); // Should be true.
As far as I can see there are a few approaches engines could take:
Arrayis implemented exactly the same way as
Object- as an associative array with string keys.
Arrayis a special case, with a
std::vector-like array backing the numeric keys, and some density heuristic to prevent insane memory use if you do
ar = 0;
Arrayis the same as
Object, and all objects get a heuristic to see if using an array would make more sense.
Really this would be simpler if there were a proper array type (cough WebGL typed arrays cough).
In SpiderMonkey, arrays are implemented basically as C arrays of jsvals. These are referred to as "dense arrays". However, if you start doing un-array-like things to them -- like treating them like objects -- their implementation is changed to something which very much resembles objects.
Moral of the story: when you want an array, use an array. When you want an object, use an object.
In V8 and Carakan (and presumably Chakra), all (non-host) objects (both those that are arrays and those that aren't) with properties whose names are array indexes (as defined in ES5) are stored as either a dense array (a C array containing some value wrapper) or a sparse array (which is implemented as a binary search tree).
The unified object representation shows through in that it affects enumeration order: with an object, SpiderMonkey and SquirrelFish both give all properties in insertion order; and with an array, they in general (there are special cases in SM at least!) array indexes first then all other properties in insertion order. V8, Carakan, and Chakra always give array indexes first then all other properties in insertion order, regardless of object type.
©2020 All rights reserved.