Sign up ×

I'm writing a JavaScript interpreter for extremely resource-constrained embedded devices (, and every time I think I have implemented some bit of JavaScript correctly I realise I am wrong.

My question now is about []. How would you implement one of the most basic bits of JavaScript correctly?

I've looked through the JavaScript spec and maybe I haven't found the right bit, but I can't find a useful answer.

I had previously assumed that you effectively had two 'maps' - one for integers, and one for strings. And the array length was the value of the highest integer plus one. However this seems wrong, according to jsconsole on chrome:

var a = [];
a[5] = 42;
a["5"]; // 42
a.length; // 6

but also:

var a = [];
a["5"] = 42;
a[5]; // 42
a.length; // 6

So... great - everything is converted into a string, and the highest valued string that represents an integer is used (plus one) to get the length? Wrong.

var a = [];
a["05"] = 42;
a.length; // 0

"05" is a valid integer - even in Octal. So why does it not affect the length?

Do you have to convert the string to an integer, and then check that when converted back to a string, it matches?

Does anyone have a reference to the exact algorithm used to store and get items in an array or object? It seems like it should be very simple, but it looks like it actually isn't!


share|improve this question
The standard says: "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 2**32-1.". – DCoder Apr 11 '13 at 19:29
If you're writing an interpreter, assumptions shouldn't be used. You should be reading the spec. – squint Apr 11 '13 at 19:45
Why don't you use existing, powerful and standard-compliant JS implementations, like V8? What I read at sounded horrible :-/ – Bergi Apr 11 '13 at 20:11
@Bergi V8, like every other JIT compiler, is rather hard to port and not a good fit for resource-constrained devices. Not only is the JIT compiler's output architecture-specific, setting up the memory for that code is also OS-specific. And a JIT compiler practically always uses more memory than a simple interpreter. They also need some time to warm up and become fast. All these make them very ill-suited for obscure devices with few resources. – delnan Apr 12 '13 at 13:37
Thanks - I did in fact try and find this in the spec before posting, but I must have been looking in the wrong place. – Gordon Williams Apr 12 '13 at 20:47

4 Answers 4

up vote 4 down vote accepted

As the specs said, and was noted by others:


That's explain why in your scenario "5" is considered an array index and "05" is not:

console.log("5" === String("5" >>> 0));
// true, "5" is equal to "5", so it's an index

console.log("05" === String("05" >>> 0));
// false, "05" is not equal to "5", so it's not an index

Note: the Zero-fill right shift is the shortest way in JS to have a substitute of ToUint32, shifting a number by zero.

share|improve this answer
Thanks - this also explains the issue with array length, which other answers didn't really address. Thanks for the link to the spec as well DCoder – Gordon Williams Apr 12 '13 at 20:47


It's possible to quote the JavaScript array indexes as well (e.g., years["2"] instead of years[2]), although it's not necessary. The 2 in years[2] eventually gets coerced into a string by the JavaScript engine, anyway, through an implicit toString conversion. It is for this reason that "2" and "02" would refer to two different slots on the years object and the following example logs true:

console.log(years["2"] != years["02"]);

So with a["5"] you are accessing the array while a["05"] sets a property on the array object.

share|improve this answer

Arrays are just objects. That means they can have additional properties which are not considered elements of the array.

If the square bracket argument is an integer, it uses it to perform an assignment to the array. Otherwise, it treats it as a string and stores it as a property on the array object.

Edit based on delnan's comment and DCoder's comment, this is how JavaScript determines if it is an appropriate index for an array (versus just a property):

share|improve this answer
The last part is not particular useful unless you define what exactly "an integer" is and what isn't. For example, is "05" an integer and why (not)? – delnan Apr 11 '13 at 19:29

Arrays are also objects.

By doing this

a["05"] = 5;

You are doing the same thing as:

a.05 = 5;

However, the above will result in a syntax error, as a property specified after a dot cannot start with a number.

So if you do this:

a = [];
a["05"] = 5;

you still have an empty array, but the property of a named 05 has the value 5.

The number x is an array index if and only if ToString(ToUint32(x)) is equal to x (so in case of "05" that requirement is not met).

share|improve this answer

Your Answer


