3

In PHP, if you do this

$var = array(); 
$var[5000] = 1;
echo count($var);

It prints 1.

In JS it makes the "missing" elements.

<script type="text/javascript">
    var fred = [];
    fred[10] = 1;
    alert(fred.length);
</script>

Alerts "11".

Can I prevent this? Is it good for anything? I'm a PHP coder trying to adapt to Javascript.

EDIT:

I'm working on an app that uses Google Maps v2 and markerManager. The code has been working for ages, but a problem has suddenly arisen in Chrome (17.0.963.56 m) where markers seem to be duplicated (or more) and then rendering moved markers goes completely wrong, often followed by a browser freeze-up. Looking in the DOM using Firebug, I found gazillions of "undefined" elements in arrays under the grid_ variable in markerManager. I figured that, if I could remove these, I might have slicker code, whether it fixes the marker problem or not. Thanks.

Pete
  • 1,289
  • 10
  • 18

2 Answers2

1

As a PHP coder, you're accustomed to array keys being fairly arbitrary. In JavaScript however, if you assign an array element numerically that doesn't exist, the array will be allocated with empty elements up to the one you created. That's the behavior you found. Objects, on the other hand, denoted by {} rather than [], accept arbitrary property names (with caution) and function a little more closely to how you're accustomed PHP's array structures functioning. This is not to say that JavaScript objects (or object literals) are a direct analogue to PHP arrays....

If what you want is a data structure with a key called "10", that is a job for an object literal (though it isn't great practice to name object properties numerically.

var fred = {};
fred["10"] = 1;

Note, the more normal syntax of dealing with an object literal is the object.property notation, but that is not valid for numeric properties:

// name as a property
fred.name = "fred";

// Syntax error...
fred.10 = 10;

// Use [] notation for numeric properties:
fred["10"] = 10;

Object literals do not have a length property, however. So you cannot do:

fred.length;
// undefined
Michael Berkowski
  • 267,341
  • 46
  • 444
  • 390
0

You may use an object instead of an array, but you loose some of the benefits of an array, like access to a length property.

<script type="text/javascript">
    var fred = {};
    fred['10'] = 1;
    // alert(fred.length);  // won't work anymore
</script>

On the other hand no extra entries will be generated and the access to a specific value works almost the same way as in an array. If you want to traverse all values, use the following:

for( var el in fred ) {
  if ( fred.hasOwnProperty( el ) ) {
    alert( fred[ el ] );
  }
}
Sirko
  • 72,589
  • 19
  • 149
  • 183
  • Thanks for the (very quick) answers. They make perfect sense. So here's a supplementary question .... is anyone familiar with MarkerManager in Google mapping? It seems to be making arrays in the way I show, resulting in huge memory usage. Or maybe I'm wrong? – Pete Feb 22 '12 at 17:13
  • Add your question as an edit to the main question or (even better) open a new question for this. At least I have no clue about the memory usage of spare arrays. – Sirko Feb 22 '12 at 17:22
  • 1
    @Pete The array may have that length, but in general in browsers don't use the array data structure (as opposed to the array data type) to store sparse arrays (i.e., arrays with holes in them — your code doesn't actually create properties called `0`, `1`, `2`, `3`, …, `9`), so the memory usage isn't O(n) where n is the length. Typically the memory usage is O(n) where n is the number of array-like properties (which is less than or equal to the length). – gsnedders Feb 22 '12 at 17:22
  • Thanks to everyone. Forgive me for asking the question in a round-about way - I'm getting used to JS and this site! – Pete Feb 22 '12 at 17:26