views:

153

answers:

6

I'm creating an array in javascript using item id's from the database whenever a corresponding button is clicked on the page. Each array entry will store a custom object.

The id's from the database for a specific can start from any number like 80123 to 80223, for that specific page of data.

so the first entry in the array will be like arr[80123].

Now when i check the length of the array it shows me 80123 ! even though theres only 1 element in it, i thought of using associative or character indexed arrays, but they lack some basic sorting operations that i would need.

Now my question is "How much memory will the array actually be consuming if there is only 1 element in it but the length of the array is 80123 ?"

More info...

The base number keeps changing 80123 is only an example.

the code im using is as follows:

function ToggleAction(actionButtonID, action) 
    {
        var extractedID = ExtractNumericIdFromTag(actionButtonID);
        var arrayIndexer = extractedID; // Can update this to make array associative

        if(actionItems[arrayIndexer] == null)
        {
            actionItems[arrayIndexer] 
                = new ActionItem(extractedID, action);
        }
        else
        {
            var ai = actionItems[arrayIndexer];
            ai.action = action;
        }
    }
+3  A: 

Arrays in Javascript are just hashes with a few special properties (mainly that the "length" property will always return one higher than the highest integer key).

I don't believe that any of the implementations would allocate a huge amount of memory just because you initially assigned something to a really high index.

jsight
This is true in that Arrays [] are Objects {} that you can add properties to but it does *not* mean that integer-indexed items in the Array are part of the object hash. They're part of the Array.
Maciek
Thats true, but the distinction has little to do with it being an array object. Integral indexed properties can be added to non-array objects as well, and indexed in the same way: "javascript:function a () { var b = {}; b[1] = 5; alert(b[1]); } a();". Its only not in the "object hash" because of the peculiarities of the rules for those keys.
jsight
A: 

How are you defining your array? If you use the Array object, you must have more than one argument for the browser to interpret the arguments as values and not the length of the array. I always try to use the literal array syntax: a = [80123]; or a = [80123,80124];

Joseph Piche
+1  A: 

Try running the following code in Firebug:

var a = [];
a[663] = "a";
a.length == 664;

this returns

true

If you then try

console.log(a)

you will get:

[undefined, undefined, undefined,  ...... , undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, "a"]

How much memory this consumes may be a matter of which engine you're using but it looks like there are a lot of slots being allocated to hold no value.

I think what you really want to use is just a plain Object-style map like this:

var a = {};
a[664] = "a";
a[323] = "b";
a

which yields:

Object 664=a 323=b

which is much more appropriate for mapping associations of id->object.

If you need to iterate through this object later on to visit all the objects, use the following code:

for(var id in a){
  if(a.hasOwnProperty(id)){
    console.log("id:",id," object:",a[id]);
  }
}
Maciek
Just because Firebug shows all of those undefined elements doesn't mean that it is allocating all of those Array elements. AFAIK Firebug is merely doing a for loop up to the Array.length property and spitting out Array[idx] || undefined. The length of the Array (memory wise) is not a one to one comparison with Array.length. An array with one element defined at the index of 100000 is not that much bigger in memory than an object with one element and a key of 100000.
Eric Ryan Harrison
I'm pretty sure the "undefined" output from toString means it hasn't actually allocated anything there. The array object probably just has a custom toString that does a simple loop over the length of the array, and any time it does a[i] for something that doesn't exist it will get 'undefined'.
Herms
A: 

I'm not sure how js arrays behave, but i think you are safe here.

Just in case you are not, I think you can consider changing the index of array based on the minimum value of id (80123 in your example), so that the array index starts at zero.

index = id - minID;

This might require changes in code in (many) other places too, so go for it only if it's absolutely necessary.

Amarghosh
Please extend the shortcuts (r, u). That's not really needed here.
Ikke
Done.. but i think u and r are widely accepted, understood and readable.
Amarghosh
@Amarghosh: I think we all have that much time to write proper english (or at least try to).
Gumbo
That sounds reasonable :) Will be careful in the future.
Amarghosh
A: 

This question has already been hinted around before:

http://stackoverflow.com/questions/1247116/which-takes-less-memory-a-javascript-array-or-javascript-object

Theoretically, in Javascript, an Array IS an Object. The only thing that is changing (in memory) in an array is the .length property. It will show the next highest array index, but it doesn't mean that there are actually that many elements in the Array allocated.

Eric Ryan Harrison
+5  A: 

Your code is not allocating that much memory, so you don't have to worry about that. Javascript Arrays are smart enough. However, I still think you should be using an Object instead of an Array in this case...

var num = 80123;
var obj = {};
obj[num] = { Name: "Josh" };

alert(obj[80123].Name);
Josh Stodola
This is a good answer. Yes, Javascript Arrays are smart enough not to waste memory, but no, you shouldn't use Arrays like this. Perfect answer. Excellent.
Eric Ryan Harrison
Thanks for the grammar correction, Beska! I've been doing that alot lately :(
Josh Stodola