for loop tip and gotcha
The usual for
loop looks like this:
var arr=['a','test','of','this']; for(var i=0;i<arr.length;i++)alert(arr[i]);
One quick tip is to use the in
construct to improve the readability:
var arr=['a','test','of','this']; for(i in arr)alert(arr[i]);
Note that I did not initialise the i
variable. for some reason, initialising in the in
construct screws up in JavaScript.
Now, the gotcha!
I was working through my JavaScript library to improve loops in this manner, and came to this function (which prototype users will recognise):
function $(){ for(var i=0,a=[];i<arguments.length;++i){ var e=arguments[i]; if(typeof e=='string')e=document.getElementById(e); if(arguments.length==1)return e; a.push(e); } return a; }
At first glance, translating the above into the in
construct looks possible:
function $(){ var a=[]; for(i in arguments){ var e=arguments[i]; if(typeof e=='string')e=document.getElementById(e); if(arguments.length==1)return e; a.push(e); } return a; }
the above code was corrected, based on Christof’s comment
However, if you do that, then you will spend hours debugging problems in code without knowing what is going wrong!
There is no syntactical problem with the above code, so you will not be alerted to any problem in that function. However, it should be noted that arguments
, although it acts like an array, is actually an object, and cannot be used as we want to use it.
I hope this saves someone some time. It certainly puzzled me for a long time!
Have you tried to set ‘a = new Array()’ before running the for-in loop? The code you posted here doesn’t work because a doesn’t have a method called ‘push’.
Christof – my mistake – I forgot to initialise the ‘a’ (pretend there’s an “var a=new Array();” (or my preferred version, “var a=[];”) line before the final ‘for’ loop. But, even with that corrected, the code still does not work. I am certain that the gotcha is real.
Another gotcha related to this is that Internet Explorer and Firefox allow you to use the
for...in
construct on NodeLists (for example, the results ofgetElementsByTagName()
), but Konqueror (and probably Safari) fails silently if you try this.