Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are JavaScript arrays implemented?

Namely, how does the following code:

var sup = new Array(5);
sup[0] = 'z3ero';
sup[1] = 'o3ne';
sup[4] = 'f3our';
document.write(sup.length + "<br />");

output '5' for the length, when all you've done is set various elements?

My 'problem' with this code is that I don't understand how length changes without calling a getLength() or a setLength() method. When I do any of the following:

a.length
a['length']
a.length = 4
a['length'] = 5

on a non-array object, it behaves like a dict / associative array. When I do this on the array object, it has special meaning. What mechanism in JavaScript allows this to happen? Does JavaScript have some type of property system which translates

a.length
a['length']

into "get" methods and

a.length = 4
a['length'] = 5

into "set" methods?

like image 766
Claudiu Avatar asked Dec 14 '08 00:12

Claudiu


People also ask

How is an array implemented in JavaScript?

For an array, if you use it with a numeric index, it returns/sets the expected indexed item. If you use it with a string, it returns/sets the named property on the array object - unless the string corresponds to a numeric value, then it returns the indexed item.

How are arrays implemented?

Implementation of arrays performs various operations like push (adding element), pop (deleting element) element at the end of the array, getting the element from particular index, inserting and deleting element from particular index.

How are arrays implemented in V8?

Once a JS array becomes large (this also includes holey arrays), V8 starts using a hash table to store the array elements. The array is now associated with the “slow” dictionary elements kind. For hot loops, the “slow” kind may be multiple orders slower than array-based kinds.

Are JavaScript arrays actually arrays?

The humble creators of JavaScript have provided us with the typeof operator. typeof is used to know the type of the variable in question. typeof used on an array returns Object rather than Array . We get this result because arrays are not really arrays in JavaScript.


4 Answers

Characteristics of a JavaScript array

  1. Dynamic - Arrays in JavaScript can grow dynamically .push
  2. Can be sparse - for example, array[50000] = 2;
  3. Can be dense - for example, array = [1, 2, 3, 4, 5]

In JavaScript, it is hard for the runtime to know whether the array is going to be dense or sparse. So all it can do is take a guess. All implementations use a heuristic to determine if the array is dense or sparse.

For example, code in point 2 above, can indicate to the JavaScript runtime that this is likely a sparse array implementation. If the array is initialised with an initial count, this could indicate that this is likely a dense array.

When the runtime detects that the array is sparse, it is implemented in a similar way to an object. So instead of maintaining a contiguous array, a key/value map is built.

For more references, see How are JavaScript arrays implemented internally?

like image 43
Samyak Jain Avatar answered Sep 20 '22 10:09

Samyak Jain


Everything in JavaScript is an object. In the case of an Array, the length property returns the size of the internal storage area for indexed items of the array. Some of the confusion may come into play in that the [] operator works for both numeric and string arguments. For an array, if you use it with a numeric index, it returns/sets the expected indexed item. If you use it with a string, it returns/sets the named property on the array object - unless the string corresponds to a numeric value, then it returns the indexed item. This is because in JavaScript array indexes are coerced to strings by an implicit toString() call. Frankly, this is just one more of those things that makes you scratch your head and say "JavaScript, this, this is why they laugh at you."

The actual underlying representation may differ between browsers (or it may not). I wouldn't rely on anything other than the interface that is supplied when working with it.

You can find out more about JavaScript arrays at MDN.

like image 54
tvanfosson Avatar answered Sep 21 '22 10:09

tvanfosson


This really depends on what you intend to do with it.

[].length is "magical".
It doesn't actually return the number of items in the array. It returns the largest instated index in the array.

var testArr = [];  testArr[5000] = "something";  testArr.length; // 5001

But the method behind the setter is hidden in the engine itself.
Some engines in some browsers will give you access to their implementations of those magic-methods. Others will keep everything completely locked down.

So don't rely on defineGetter and defineSetter methods, or even, really, __proto__ methods, unless you know which browsers you know you're targeting, and which you aren't.

This will change in the future, where opt-in applications written in ECMAScript Next/6 will have access to more.

ECMAScript 5-compliant browsers are already starting to offer get and set magic methods in objects and there's more to come... ...but it's probably a while away before you can dump support for oldIE and a tonne of smartphones, et cetera...

like image 24
Norguard Avatar answered Sep 21 '22 10:09

Norguard


It is important to know that when you do sup['look'] = 4; you are not using an associative array, but rather modify properties on the object sup.

It is equivalent to sup.look = 4; since you can dynamically add properties on JavaScript objects at any time. sup['length'] would for an instance output 5 in your first example.

like image 26
finpingvin Avatar answered Sep 21 '22 10:09

finpingvin