Javascript Gotchas : for vs for…in

Since the day I first acquainted myself with javascript, I thought ‘for’ and ‘for..in’ served pretty much the same purpose. I always considered the latter to be merely of syntactic ease to a developer. Today I found out an important difference between these two constructs.

Suppose we run this code snippet:

var array = [1,2,3,4,5];
array.capacity = 10;

var str = '';
for(var i in array)
  str += array[i];

var str2 = '';
for(i=0; i < array.length; i++)
  str2 += array[i];

So by the end of the code execution, what are the values of str and str2? Before executing this code I always thought both will give the same result but the fact is :
str2 = ‘12345’ while str = ‘1234510’

If the highlighted line(No.2) is removed, both str and str2 give the same value ‘12345’.

If you closely read the description of the for…in consctruct from W3Schools, you’ll find the reason behind this difference in behavior. It says

“The for…in statement loops through the elements of an array or through the properties of an object.”

What entices us to believe that both ‘for’ and ‘for..in’ are alike is the way these have been demonstrated. Almost all the top search result from google, give the code of iterating array elements while explaining the ‘for…in’ construct, so we never use it for accessing properties. Although, we usually do not keep properties in array objects but this behavior results when we get an array object from an external javascript library. Here is the example code for jQuery that reveals this difference:

var a = '[{"a":1},{"a":2},{"a":3}]';
var array = $.parseJSON(a);
for(var i in array)
  //process array[i]

Useful knowledge !

Advertisements

, , ,

  1. #1 by Dan Sickles on December 27, 2010 - 8:42 pm

    This is actually an Ecmascript 3 issue (javascript 1.3 1998). This was solved with for each.. in Javascript 1.6 (Firefox 1.5 2005). It is also solved in Ecmascript 5 (12/2009):

    http://davidflanagan.com/Talks/es5/slides.html

    Yes, Ecmascript 3, for now, remains the LCD for cross-browser scripting.

    https://developer.mozilla.org/en/new_in_javascript_1.6

  2. #2 by Milos Jovanovic on December 29, 2010 - 11:58 pm

    There is a lapsus in second code snippet:
    var a = '[{"a":1},{"a":2},{"a":3}]';
    var array = $.parseJSON(a);
    for(var i in a)
    //process array[i]

    This way you would process string a’s characters one by one

    One would probably want to process parsed object so it should be
    for(var i in array)

    • #3 by Syed Muhammad Faraz on December 30, 2010 - 12:06 am

      Good catch! It was a typo.
      I have corrected it now.

      Thanks for notifying…

  3. #4 by Ali on December 30, 2010 - 6:05 pm

    good i also tested now

  4. #5 by Umair Jabbar on July 11, 2011 - 12:42 pm

    Try applying a for-loop for this

    var a = []; a[0] = 1; a[1] = 2; a[2] = 3; a[10] = 11;

    See if you find anything interesting !

    • #6 by Syed Muhammad Faraz on July 11, 2011 - 9:50 pm

      Do you mean this:
      var a = []; a[0] = 1; a[1] = 2; a[2] = 3; a[10] = 11;
      for(var i=0;i<a.length;i++) alert(a[i]);

      I ran it and it worked as expected, giving 'undefined' for missing keys…

      • #7 by Umair Jabbar on July 12, 2011 - 11:57 am

        the remaining undefined are something unexpected, logically you shouldnt be allowed to set a key which is not in sequence

      • #8 by Syed Muhammad Faraz on July 12, 2011 - 11:14 pm

        Yeah right. But it becomes so much predictable when you know how bad javascript is by design :).
        parseInt(’05’) gives 5 while parseInt(’09’) gives 0.

        Try these two snippets:
        1)
        (function(){
        return
        {test:8};
        })();

        2)
        (function(){
        return{test:8};
        })();

        Both return different results.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: