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.

3 Answers 3

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
Sign up to request clarification or add additional context in comments.

Comments

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 ] );
  }
}

4 Comments

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?
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.
@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).
Thanks to everyone. Forgive me for asking the question in a round-about way - I'm getting used to JS and this site!
0

In JS it makes the "missing" elements.

Actually, it doesn't. What you have there is a sparse array. In that case the length property is misleading: it doesn't tell you how many elements there are in the array. It just adapts to whatever the greatest index is that you have assigned a value to, plus one. You can even assign that length property a greater value:

const fred = [];
fred[10] = 1;
console.log(fred.length);
fred.length = 20;
console.log(fred.length);

That operation does not fill up the array with more entries either. To count how many entries really are there, you could check Object.keys(fred).length and you'll see there is just one (enumerable) property:

const fred = [];
fred[10] = 1;
console.log(Object.keys(fred).length);

This also demonstrates that you didn't really need to define fred as an array, but could have just as well defined it as a plain object:

const fred = {};
fred[10] = 1;
console.log(Object.keys(fred).length);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.