4

Consider the following example:

Code:

var array = [];
array[4] = "Hello World";

Result:

[undefined, undefined, undefined, undefined, "Hello World"]

It looks rather inefficient to be able to just declare where in the array you want your value to reside. Think in terms of big arrays (100,000+ indexes).

Is this actually an inefficient use of arrays in JavaScript, or are arrays handled in such a way that n indexes aren't actually declared undefined? (i.e. is this just pretty printed to illustrate the empty indexes?)

Note: The suggested duplicate of this question is wrong. This is not concerning zero-based indexes. I am already aware that arrays start from 0!

GG.
  • 21,083
  • 14
  • 84
  • 130
Matthew Layton
  • 39,871
  • 52
  • 185
  • 313

3 Answers3

4

Your assumption is correct. JS arrays are objects, and an array declaration, like

a = ['a','b','c']

is just a shortcut for

a = {
   "0": "a",
   "1": "b",
   "2": "c"
}

Respectively, a=[]; a[4]='foo' is the same as

a = {
  "4": "foo"
}

The bunch of undefineds you see in the console is just an artifact of how the console dumps arrays, they don't actually exist.

The only difference between arrays and ordinary objects is that arrays have a "length" property which is handled in a special way. length is always equal to the max of numeric indexes assigned so far plus one:

a = [];
a[100] = 'x';
a.length; // 101

NB: I'm talking about an "ideal" JS implementation as described in the standard, specific implementations might provide under-the-hood optimizations and store arrays in a different way.

Matthew Layton
  • 39,871
  • 52
  • 185
  • 313
georg
  • 211,518
  • 52
  • 313
  • 390
1

JavaScript arrays work that way. When you declare a new array:

var arr = [];

The length will be 0. And there will be no elements.

And if you insert at the 5th index:

arr[5] = 10;

Then, JavaScript engine fills the previous numeric indices with undefined values. Thereby making the array length to be 6 and not 1. If you see the array contents, it would be:

arr => array(
    undefined,
    undefined,
    undefined,
    undefined,
    undefined,
    10
)

I have already asked a question about this, but I am not able to find it. The question is: Wrong representation of JavaScript Array Length.

Copying the accepted answer from the above said question:

The .length is defined to be one greater than the value of the largest numeric index. (It's not just "numeric"; it's 32-bit integer values, but basically numbered properties.)

Conversely, setting the .length property to some numeric value (say, 6 in your example) has the effect of deleting properties whose property name is a number greater than or equal to the value you set it to.

Community
  • 1
  • 1
Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252
1

It will all depend on the JavaScript interpreter as to exactly how the internal structure is handled — which would define whether it is handled in an inefficient way or not.

My simplified assumption is that actually causing the array to be printed out is the only point where those undefineds are discovered. Basically meaning that it is only through access that those particular indexes are found to have a value of undefined (i.e. not allocated). Basically the following would be different (in my thinking):

var a = []; a[100] = 1;

to that of:

var a = []; for ( var i=0; i<=99; i++ ) { a[i] = undefined; } a[100] = 1;

The latter would have all 100 indexes taking up recorded space. Whereas the former would only have one index recorded.

Basically until an index is defined, it won't take up stored space. The internal array structure will just record the indexes that are defined and the largest index.

The reality I'm sure is probably more involved, take this overview of the v8 engine (I can't link directly to the Array section because someone messed up their anchor IDs ;). It seems there are two types of storage for the v8 engine. One designed to handle arrays that are linear, and well defined, and the other to handle the type we are talking about (whereby it uses a hash) which won't work in an linear indexed manner, it will use "hashed" key locations instead.

http://www.html5rocks.com/en/tutorials/speed/v8/#toc-topic-numbers

Pebbl
  • 34,937
  • 6
  • 62
  • 64