Writing better javascript – Part 4
I am not going to be writing about a JavaScript technique here but just about a JavaScript syntax which sometimes is not well understood. Arrays in JavaScript can be used a couple of ways like below.
var test = new Array();
test[0] = “Here is something”;
test[“name”] = “Here is another thing”;
As you can see, the array instance above is indexed using an integer and then a string. But an array by definition should only be indexed by an integer and not a string. So, how does JavaScript allow this? Well, JavaScript really doesn’t. Then how does the above piece of code work? Well, when you write something like “test[‘name’] = ‘Here is another thing'” what is really happening is that the value specified is not added to the list of items in the array but it gets stored in a property called ‘name’ on the array. The only reason the above syntax works is because an Array in JavaScript is also an Object. So, the value can also be retrieved by referencing ‘test.name’.
One last thing that I want to add to this post is how to iterate over all the properties of an Object.
var test = new Object();
test[“firstname”] = “Bill”;
test.lastname = “Gates”;
for(var item in test) {
alert(test[item]);
}
//this should alert ‘Bill’ and ‘Gates’
This may not be news to everybody but it took me a while to realize this when i started writing JavaScript.
Actually your code would alert ‘firstname’ and ‘lastname’. Your code would have to be:
for (var item in test) {
alert(test[item]);
}
to alert ‘Bill’ and ‘Gates’.
Another thing about the for/in statement. Although it may alert ‘Bill’ and ‘Gates’, but the ECMA script spec does not guarantee the order. So it can possibly alert ‘Gates’ and ‘Bill’ some other time. If you want to have consistent order, use an index based array.
This also has the bad problem of forcing all arrays to be treated as hashes – which means if you fill an array with 30 items, it takes longer to get to the 30th item as it does the 1st item. This bears out in benchmarks.
However, Safari and Google Chrome are smart enough to detect when you really want an array – avoiding the performance hit.
And this is why you should never mess with
Object.prototype
… otherwise whatever you cleverly added will happily show up every time you iterate over any object.Which benchmarks? And what functioning “hash” is anything other than O(1)?
Don’t know why my comment didn’t get posted… hey Vish, you don’t want comments from me, just say so… :).
The code:
for(var item in test) {
alert(item);
}
will alert ‘firstname’ and ‘secondname’.
To alert ‘Bill’ and ‘Gates’ the code needs to be
for(var item in test) {
alert(test[item]);
}
Also, the ECMA script does NOT guarantee the order in the for/in statement. So its possible that you can get ‘Gates’ and ‘Bill’. If you want the order to be maintained, use an index based Array.
Hi Jayant,
Thank you for catching that. And I appreciate all your comments and suggestions. They are always welcome. That’s what happens when I stay up writing blog posts way into the night using a text editor and not an IDE… I fixed it in the post.
Vish
Remember that for(var item in test) also iterates on your methods and not only the properties.
For the same reason NEVER use this syntax to iterate on arrays. It could cause a lot of issues with extension libraries that adds methods or properties to Array. With arrays always iterate using an integer from 0 to length.