How does an array actually work in javascript - javascript

i hope my question isn't that dumb. But i've wondered how arrays actually work in javascript. Espacially getting an element by index.
Let's assume i have an array called myFirstArray with the elements [1,2,3,4].
When i type myFirstArray[3], how does it work to get the fourth element from that array?
Does it loop through? So everytime i want the last element of an array it is looping through the whole array?
Same goes with adding an element to an Array. Do it loop always through the array do find the last element in the Array?
I'm asking because i implemented a linkedList into Javascript and im wondering if it is more efficient than an normal array.

The implementation of arrays in Javascript is a little different from how it's done in most other languages.
An array isn't just a list of items, instead it is a associative array. Items aren't stored after each other, instead they are stored as discrete key-value pairs. If you for example put values at index 3 and 5, the array doesn't contain undefined items to fill up the gaps, it just has the values that are set.
With code like this:
var a = [];
a[3] = 1;
a[5] = 2;
The data that is stored in the array doesn't look like this:
[ undefined, undefined, undefined, 1, undefined, 2 ]
Rather it looks like this:
{
"3": 1,
"5": 2,
"length": 6
}
The items in the array is stored as properties in the array object, it's just that the array handles properties with a numeric key in a special way, i.e. adjusting the length property if needed.
The implementation of the key-value collection is done using a hash table (or perhaps something even more efficient, depending on the Javascript engine), so accessing an item is close to an O(1) operation, i.e. it doesn't loop through all properties until it finds the right one.

How array access is realized is up to the JavaScript engine itself and may hence differ from engine to engine.
I would guess though that arrays are still blocks of memory in most engines. If you access an element, the array is not circled through. Rather the memory address for that specific element is calculated (memory_offset_of_the_first_element + size_of_element * desired_index) and then the element can be gathered from there. Insertions and deletions are a more complex and expensive. In worst case the whole array needs to be copied and adjusted.
Lamar provided a good overview in When to use a linked list over an array/array list?.

In Javascript there are standard built-in objects and one of those objects is Array. Array is high-level global object and is used as a constructor for arrays.
Array elements are object properties that can be accessed through bracket notation. In other languages you would call Javascript arrays as sparse arrays (ex: Wolfram).

Related

how does javascript move to a specific index in an array?

This is more a general question about the inner workings of the language. I was wondering how javascript gets the value of an index. For example when you write array[index] does it loop through the array till it finds it? or by some other means? the reason I ask is because I have written some code where I am looping through arrays to match values and find points on a grid, I am wondering if performance would be increased by creating and array like array[gridX][gridY] or if it will make a difference. what I am doing now is going through a flat array of objects with gridpoints as properties like this:
var array = [{x:1,y:3}];
then looping through and using those coordinates within the object properties to identify and use the values contained in the object.
my thought is that by implementing a multidimensional grid it would access them more directly as can specify a gridpoint by saying array[1][3] instead of looping through and doing:
for ( var a = 0; a < array.length; a += 1 ){
if( array[a].x === 1 && array[a].y === 3 ){
return array[a];
}
}
or something of the like.
any insight would be appreciated, thanks!
For example when you write array[index] does it loop through the array till it finds it? or by some other means?
This is implementation defined. Javascript can have both numeric and string keys and the very first Javascript implementations did do this slow looping to access things.
However, nowadays most browsers are more efficient and store arrays in two parts, a packed array for numeric indexes and a hash table for the rest. This means that accessing a numeric index (for dense arrays without holes) is O(1) and accessing string keys and sparse arrays is done via hash tables.
I am wondering if performance would be increased by creating and array like array[gridX][gridY] or if it will make a difference. what I am doing now is going through a flat array of objects with gridpoints as properties like this array[{x:1,y:3}]
Go with the 2 dimension array. Its a much simpler solution and is most likely going to be efficient enough for you.
Another reason to do this is that when you use an object as an array index what actually happens is that the object is converted to a string and then that string is used as a hash table key. So array[{x:1,y:3}] is actually array["[object Object]"]. If you really wanted, you could override the toString method so not all grid points serialize to the same value, but I don't think its worth the trouble.
Whether it's an array or an object, the underlying structure in any modern javascript engine is a hashtable. Need to prove it? Allocate an array of 1000000000 elements and notice the speed and lack of memory growth. Javascript arrays are a special case of Object that provides a length method and restricts the keys to integers, but it's sparse.
So, you are really chaining hashtables together. When you nest tables, as in a[x][y], you creating multiple hashtables, and it will require multiple visits to resolve an object.
But which is faster? Here is a jsperf testing the speed of allocation and access, respectively:
http://jsperf.com/hash-tables-2d-versus-1d
http://jsperf.com/hash-tables-2d-versus-1d/2
On my machines, the nested approach is faster.
Intuition is no match for the profiler.
Update: It was pointed out that in some limited instances, arrays really are arrays underneath. But since arrays are specialized objects, you'll find that in these same instances, objects are implemented as arrays as well (i.e., {0:'hello', 1:'world'} is internally implemented as an array. But this shouldn't frighten you from using arrays with trillions of elements, because that special case will be discarded once it no longer makes sense.
To answer your initial question, in JavaScript, arrays are nothing more than a specialized type of object. If you set up an new Array like this:
var someArray = new Array(1, 2, 3);
You end up with an Array object with a structure that looks more-or-less, like this (Note: this is strictly in regards to the data that it is storing . . . there is a LOT more to an Array object):
someArray = {
0: 1,
1: 2,
2: 3
}
What the Array object does add to the equation, though, is built in operations that allow you to interact with it in the [1, 2, 3] concept that you are used to. push() for example, will use the array's length property to figure out where the next value should be added, creates the value in that position, and increments the length property.
However (getting back to the original question), there is nothing in the array structure that is any different when it comes to accessing the values that it stores than any other property. There is no inherent looping or anything like that . . . accessing someArray[0] is essentially the same as accessing someArray.length.
In fact, the only reason that you have to access standard array values using the someArray[N] format is that, the stored array values are number-indexed, and you cannot directly access object properties that begin with a number using the "dot" technique (i.e., someArray.0 is invalid, someArray[0] is not).
Now, admittedly, that is a pretty simplistic view of the Array object in JavaScript, but, for the purposes of your question, it should be enough. If you want to know more about the inner workings, there is TONS of information to be found here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
single dimension hash table with direct access:
var array = {
x1y3: 999,
x10y100: 0
};
function getValue(x, y) {
return array['x' + x + 'y' + y];
}

JavaScript Inner-Array

Is it good practice to create a JavaScript array inside another array?
Example: I would create an array, "array1", which would contain objects of "array2" and "array3".
Example Code:
var array1 = [];
var array2 = []
array1.push(array2);
The reason I ask this question, is that with a multidimensional array, it seems hard to get the length of all dimensions, however, with this "inner-array," you could get the dimensions quite easily:
array1[0].length
Note that generally it is called "jagged array" (array of arrays) which is not necessary represent rectangular matrix (usually multidimensional arrays that have same number of elements on each level).
JavaScript does not support what usually considered "multidimensional arrays" unlike some other languages where you can do something like matrix = new int[10,20]. So this is the only way to create "multidimensional array" in JavaScript. This post How to initialize a jagged array in JavaScript? may give you other way to initialize the array.
If using it for matrix manipulation code be careful when adding inner arrays: usually code would expect rectangular shape(like nested for loops) and may fail if some inner arrays have wrong dimensions.
Is it good practice to create a JavaScript array inside another array?
The elements contained in an array can be everything, even other arrays. So there's nothing bad in doing that.
The reason I ask this question, is that with a multidimensional array,
it seems hard to get the length of all dimensions, however, with this
"inner-array," you could get the dimensions quite easily
Your "inner-array" is, in fact, a multidimensional array.

Javascript hash table vs associative arrays

I'm new to javascript and I cannot find answer about some issues, one is the following:
Why in js would be useful an hash table data structure when we can use objects as associative arrays that is simple to use and have a very good performance?
why in js would be useful an hash table data structure when we can use
objects as associative arrays that is simple to use and have a very
good performance?
The only reason I can imaging to implement an hash table data structure is if you want to preserve the ordering of the elements. The for…in loop for objects doesn't guarantee to you in which order the properties ("keys") are returned, even if commonly you can obtain them in chronological order (last added, last returned). But it's not guarantee. For instance, old version of Opera returned the properties in an apparently random order. So, if you need an "ordered" hash table, you need to implement it by yourself.
A javascript hashtable and javascript associative array (and javascript objects) are all the same thing in the underline implementation. These are just different syntax.
So :
var a = {};
a.id = "aa";
is same as:
var a = new Object();
a.id = "aa";
Which is is same as:
var a = {};
a["id"] = "aa";
Associative arrays and hashtables are the same.
These expressions usually means the same too: dictionary, associative array, hashmap, map, hashtable and... the list goes on.
There is a difference between simple ARRAY and HASHTABLE though.
If you want to search an item in an array, the more items you have inside it, the longer will the search takes.
For example searching an item in an array with 10000 elements could takes 100 times longer than in an array with 100 elements.
With hashtables, no matter how many elements you have, the performance remains the same. (Be it 100 elements or even 99999999 elements...)

Do undefined values in Javascript arrays use any memory or get iterated over in a for-in loop?

I'm building an Entity System for a game, and basically I'm not sure whether I should use simple objects (dictionaries) or arrays to to store the entities/components by their id.
My biggest issue is that I didn't want a dynamic entity id. If the id was just a string (using the dictionary to store entities), then it would always be valid and I could use storage[id] to get to that entity.
If I used arrays, I thought, the id's of entities, which would represent an index in the storage array, would change. Consider this array of entities:
[
Entity,
Entity, //This one is being removed.
Entity
];
If I was to remove the second entity in that array, I thought that the id required to access the third array would have to change to the id (index) of the (now removed) second entity. That's because I thought about deleting in terms of splice()ing.
But, I could use the delete expression to turn the element (an entity) into an undefined! And, if it's true that arrays in Javascript are actually just objects, and objects logically have infinitely many undefined values, does that mean that undefined values inside arrays don't use up memory?
Initially, I though that arrays were implemented in a way that they were aligned in memory, and that an index was just an offset from the first element, and by this logic I thought that undefined values would use at least the memory of a pointer (because I, actually, thought that pointers to elements are aligned, not elements themselves).
So, if I stored 10k+ entities in this array, and deleteed half of them, would the 5k undefined's use any memory at all?
Also, when I do a for entity in array loop, would these undefined elements be passed?
Also, where can I find resources to see how arrays are actually supposed to be implemented in Javascript? All I can find are general explanations of arrays and tutorials on how to use them, but I want to find out all about these little quirks that can prove important in certain situations. Something like a "Javascript quirks" site would be great.
Arrays are not just objects. In particular the length property is very magic.
Of course, a JavaScript engine is allowed to represent the array internally in any way it chooses, as long as the external API remains the same. For instance, if you set randomly separated values then they may be stored as a hash, but if you set consecutive values then they may be optimised into an array.
for ... in does not enumerate properties that are not set. This includes an array literal that skips values e.g. [true, , false], which will only enumerate indices 0 and 2.

How do modern browsers implement JS Array, specifically adding elements?

By this I mean when calling .push() on an Array object and JavaScript increases the capacity (in number of elements) of the underlying "array". Also, if there is a good resource for finding this sort of information for JS, that would be helpful to include.
edit
It seems that the JS Array is like an object literal with special properties. However, I'm interested in a lower level of detail--how browsers implement this in their respective JS engines.
There cannot be any single correct answer to this qurstion. An array's mechanism for expanding is an internal implementation detail and can vary from one JS implementation to another. In fact, the Tamarin engine has two different implementations used internally for arrays depending on if it determines if the array is going to be sequential or sparse.
This answer is wrong. Please see #Samuel Neff's answer and the following resources:
http://news.qooxdoo.org/javascript-array-performance-oddities-characteristics
http://jsperf.com/array-popuplation-direction
Arrays in JavaScript don't have a capacity since they aren't real arrays. They're actually just object hashes with a length property and properties of "0", "1", "2", etc. When you do .push() on an array, it effectively does:
ary[ ary.length++ ] = the_new_element; // set via hash
Javascript does include a mechanism to declare the length of your array like:
var foo = new Array(3);
alert(foo.length); // alerts 3
But since arrays are dynamic in javascript there is no reason to do this, you don't have to manually allocate your arrays. The above example does not create a fixed length array, just initializes it with 3 undefined elements.
// Edit: I either misread your question or you changed it, sorry I don't think this is what you were asking.

Categories

Resources