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!

3 Comments.

  1. 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’.

  2. 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.

  3. 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 of getElementsByTagName()), but Konqueror (and probably Safari) fails silently if you try this.

%d bloggers like this: