Edit: apparently this answer was a bit too terse/fuzzy for some.
As I previously stated, the memory allocation behavior in your example is unspecified. That is, the the ECMAScript specification doesn't tell engines how much memory to (not) allocate for unassigned array slots.
What really happens under the hood, then, varies a lot by engine. For example, a given engine may choose to pre-allocate 100bytes of memory for all new arrays with the assumption that they will be packed, and then subsequently de-opt into a sparse array implementation if a certain ratio of assigned values to array size isn't met. That's all up to the discretion of the engine implementors though, since, again, the language specification is silent here.
That being said, array sparsity is a rather critical concept to the language itself (despite memory allocation thereof being unspecified). For example, the specifications for several of the built-in Array.prototype
methods (such as .map()
and .forEach()
) do explicitly define iteration behavior over "holes" in arrays (that is, indices that have never been assigned to). Additionally, real-world code often takes advantage of array sparsity as well. These factors all put a lot of pressure on engine implementors to not have their engine fall over and die when encountering code like:
var arr = [];
arr[4294967295] = 'allocate this';
In fact, go ahead and try it. You'll notice that any engine worthy of note (V8, Nitro, SpiderMonkey, Nashorn, Rhino, Chakra, etc.) handle it just fine.
Now, why it works in each of these engine is it's own discussion, but summarily speaking, it's because they all expect, and can adequately cope with, sparse arrays.