difference between 'for (var i=0; i < x.length; i++)' and 'for (var iin x)'

Discussion in 'Javascript' started by erdibalint, Feb 20, 2008.

  1. erdibalint

    erdibalint Guest

    Hi,

    I've come across the problem and I spent a remarkable amount of time
    debugging at the end of which I found the cause of the bug to be the
    following:

    var arr = ['a', 'b', 'c', 'd'];
    var arr2 = [];
    for (var i=0; i < arr.length; i++) {
    var elt = arr;
    arr2.push(elt);
    }
    // arr2 equals ["a", "b", "c", "d"]

    var arr = ['a', 'b', 'c', 'd'];
    var arr2 = [];
    for (var i in arr) {
    var elt = arr;
    arr2.push(elt);
    }
    // arr2 equals ["a", "b", "c", "d", function()]

    I thought that the second type of for loop is identical to the first
    one and just adds syntetic sugar. I guess I was wrong, can anyone shed
    some light on how the two loops are different?

    Thank you,
    Bálint
     
    erdibalint, Feb 20, 2008
    #1
    1. Advertising

  2. erdibalint

    RobG Guest

    Re: difference between 'for (var i=0; i < x.length; i++)' and 'for(var i in x)'

    erdibalint wrote:
    > Hi,
    >
    > I've come across the problem and I spent a remarkable amount of time
    > debugging at the end of which I found the cause of the bug to be the
    > following:
    >
    > var arr = ['a', 'b', 'c', 'd'];
    > var arr2 = [];
    > for (var i=0; i < arr.length; i++) {
    > var elt = arr;
    > arr2.push(elt);
    > }
    > // arr2 equals ["a", "b", "c", "d"]
    >
    > var arr = ['a', 'b', 'c', 'd'];
    > var arr2 = [];
    > for (var i in arr) {
    > var elt = arr;
    > arr2.push(elt);
    > }
    > // arr2 equals ["a", "b", "c", "d", function()]
    >
    > I thought that the second type of for loop is identical to the first
    > one and just adds syntetic sugar. I guess I was wrong, can anyone shed
    > some light on how the two loops are different?


    "syntactic sugar"?

    The first loops over the indexes of arr, from 0 to (arr.length - 1).

    The second loops over the enumerable properties of arr, which, for an
    unmodified Array and where Array.prototype remains unmodified, will be
    those index[1] properties that have been assigned a value.

    However, if either the array object itself (arr) or Array.prototype have
    been modified with additional properties that aren't indexes, the second
    will also loop over those also whereas the first will not.

    A for..in loop is typically only used for sparse arrays, i.e. where the
    length is large but only a few values have been assigned to some
    indexes, where it is significantly faster than iterating over all the
    indexes from 0 to length-1.

    Some libraries extend Array.prototype and some script authors treat
    array objects as "hashes". Both of which may cause for..in loops to do
    unexpected things that otherwise they may not.


    1. An array index is just a property that has an integer as its property
    name, although the index is still a string.


    --
    Rob
    "We shall not cease from exploration, and the end of all our
    exploring will be to arrive where we started and know the
    place for the first time." -- T. S. Eliot
     
    RobG, Feb 20, 2008
    #2
    1. Advertising

  3. erdibalint

    erdibalint Guest

    Re: difference between 'for (var i=0; i < x.length; i++)' and 'for(var i in x)'

    Thank you for your clear explanation. Synthetic sugar means a simpler
    (more concise or easier to retain) form of an expression that does the
    same (has the same semantics) as the more complex one.

    On Feb 20, 12:49 pm, RobG <> wrote:

    > "syntactic sugar"?
    >
     
    erdibalint, Feb 20, 2008
    #3
  4. Re: difference between 'for (var i=0; i < x.length; i++)' and 'for(var i in x)'

    Randy Webb <> writes:

    > Is there any assurance that for-in will give them back to you in any
    > predictable order? :)


    The specification of the for-in statement says:
    "The order of enumeration is defined by the object."
    A quick scan doesn't show any specification for Array objects.

    /L
    --
    Lasse Reichstein Nielsen -
    DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
    'Faith without judgement merely degrades the spirit divine.'
     
    Lasse Reichstein Nielsen, Feb 20, 2008
    #4
  5. erdibalint

    RobG Guest

    Re: difference between 'for (var i=0; i < x.length; i++)' and 'for(var i in x)'

    On Feb 21, 5:43 am, Randy Webb <> wrote:
    > RobG said the following on 2/20/2008 6:49 AM:
    >
    >
    >
    > > erdibalint wrote:
    > >> Hi,

    >
    > >> I've come across the problem and I spent a remarkable amount of time
    > >> debugging at the end of which I found the cause of the bug to be the
    > >> following:

    >
    > >> var arr = ['a', 'b', 'c', 'd'];
    > >> var arr2 = [];
    > >> for (var i=0; i < arr.length; i++) {
    > >> var elt = arr;
    > >> arr2.push(elt);
    > >> }
    > >> // arr2 equals ["a", "b", "c", "d"]

    >
    > >> var arr = ['a', 'b', 'c', 'd'];
    > >> var arr2 = [];
    > >> for (var i in arr) {
    > >> var elt = arr;
    > >> arr2.push(elt);
    > >> }
    > >> // arr2 equals ["a", "b", "c", "d", function()]

    >
    > >> I thought that the second type of for loop is identical to the first
    > >> one and just adds syntetic sugar. I guess I was wrong, can anyone shed
    > >> some light on how the two loops are different?

    >
    > > "syntactic sugar"?

    >
    > > The first loops over the indexes of arr, from 0 to (arr.length - 1).

    >
    > > The second loops over the enumerable properties of arr, which, for an
    > > unmodified Array and where Array.prototype remains unmodified, will be
    > > those index[1] properties that have been assigned a value.

    >
    > Is there any assurance that for-in will give them back to you in any
    > predictable order? :)


    No, well spotted.

    As Lasse says, the spec doesn't define any particular order so none
    should be expected.

    There is useful thread here:

    <URL:
    http://groups.google.com.au/group/c...k=gst&q="for..in" sort order#21c3348ba41b2742
    >



    --
    Rob
     
    RobG, Feb 21, 2008
    #5
  6. erdibalint

    Evertjan. Guest

    Re: difference between 'for (var i=0; i < x.length; i++)' and 'for (var i in x)'

    RobG wrote on 21 feb 2008 in comp.lang.javascript:

    >> Is there any assurance that for-in will give them back to you in any
    >> predictable order? :)

    >
    > No, well spotted.
    >
    > As Lasse says, the spec doesn't define any particular order so none
    > should be expected.
    >


    There are many applications where the order is not important,
    just the manipulation on each object member is:

    var a = [1,2,3];
    a['large'] = 999;
    for (var n in a)
    a[n]++;
    document.write(a.join('-'));
    document.write('<br>');
    document.write(a['large']);

    shows:

    2-3-4
    1000

    ========================

    To get some idea of the undocumented predictability of the order:

    var a = [];
    a.push(1,2,3);
    a['large'] = 999;
    a.push(4,5,6);
    for (var n in a)
    document.write(a[n] + ' [' + n + ']<br>');

    both IE7 and FF2 show:

    1 [0]
    2 [1]
    3 [2]
    999 [large]
    4 [3]
    5 [4]
    6 [5]


    --
    Evertjan.
    The Netherlands.
    (Please change the x'es to dots in my emailaddress)
     
    Evertjan., Feb 21, 2008
    #6
  7. erdibalint

    RobG Guest

    Re: difference between 'for (var i=0; i < x.length; i++)' and 'for(var i in x)'

    Evertjan. wrote:
    > RobG wrote on 21 feb 2008 in comp.lang.javascript:
    >
    >>> Is there any assurance that for-in will give them back to you in any
    >>> predictable order? :)

    >> No, well spotted.
    >>
    >> As Lasse says, the spec doesn't define any particular order so none
    >> should be expected.
    >>

    >
    > There are many applications where the order is not important,
    > just the manipulation on each object member is:

    [...]

    > To get some idea of the undocumented predictability of the order:


    To get some idea of the undocumented *un*predictability of the order,
    try the following in Firefox:

    <div id="xx"></div>
    <script type="text/javascript">
    function foo(obj) {
    var props = {alpha:'alpha', gamma:'gamma',
    delta:'delta', beta:'beta'};
    for (var p in props) obj[p] = props[p];
    var x = [];
    for (p in obj){
    if (p in props){
    x.push(p);
    }
    }
    return x;
    }
    window.onload = function(){
    document.getElementById('xx').innerHTML =
    foo(this).join('<br>');
    }
    </script>

    --
    Rob
    "We shall not cease from exploration, and the end of all our
    exploring will be to arrive where we started and know the
    place for the first time." -- T. S. Eliot
     
    RobG, Feb 21, 2008
    #7
  8. erdibalint

    Evertjan. Guest

    Re: difference between 'for (var i=0; i < x.length; i++)' and 'for (var i in x)'

    RobG wrote on 21 feb 2008 in comp.lang.javascript:

    > Evertjan. wrote:
    >> RobG wrote on 21 feb 2008 in comp.lang.javascript:
    >>
    >>>> Is there any assurance that for-in will give them back to you in any
    >>>> predictable order? :)
    >>> No, well spotted.
    >>>
    >>> As Lasse says, the spec doesn't define any particular order so none
    >>> should be expected.
    >>>

    >>
    >> There are many applications where the order is not important,
    >> just the manipulation on each object member is:

    > [...]
    >
    >> To get some idea of the undocumented predictability of the order:

    >
    > To get some idea of the undocumented *un*predictability of the order,
    > try the following in Firefox:
    >
    > <div id="xx"></div>
    > <script type="text/javascript">
    > function foo(obj) {
    > var props = {alpha:'alpha', gamma:'gamma',
    > delta:'delta', beta:'beta'};
    > for (var p in props) obj[p] = props[p];
    > var x = [];
    > for (p in obj){
    > if (p in props){
    > x.push(p);
    > }
    > }
    > return x;
    > }
    > window.onload = function(){
    > document.getElementById('xx').innerHTML =
    > foo(this).join('<br>');
    > }
    > </script>


    Using the global object inpractical to say the least!

    This is only because the global object acts differently in FF by
    searching the global object from the end [end = last addded member],
    possibly to get a speed bonus. If you change the last code part to:

    window.onload = function(){
    var q = {};
    document.getElementById('xx').innerHTML =
    foo(q).join('<br>');
    }

    .... there is no output difference between IE and FF.

    =================================================

    btw, please try this in IE and FF to see the real working:

    <div id="xx"></div>
    <script type="text/javascript">
    function foo(obj) {
    var props = {alpha:'alpha', beta:'beta',
    gamma:'gamma', delta:'delta'};
    for (var p in props) obj[p] = props[p];
    var x = [];
    for (p in obj){
    //if (p in props){
    x.push(p);
    //}
    }
    return x;
    }
    window.onload = function(){
    document.getElementById('xx').innerHTML =
    foo(this).join('<br>');
    }
    </script>

    To see what I mean.


    --
    Evertjan.
    The Netherlands.
    (Please change the x'es to dots in my emailaddress)
     
    Evertjan., Feb 21, 2008
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. thomson
    Replies:
    10
    Views:
    2,512
    Eliyahu Goldin
    Jun 20, 2005
  2. thomson
    Replies:
    0
    Views:
    397
    thomson
    Jun 20, 2005
  3. daniele.g
    Replies:
    4
    Views:
    487
    Joe Pfeiffer
    Jul 15, 2011
  4. Shea Martin

    difference between @var and self.var

    Shea Martin, Jun 21, 2006, in forum: Ruby
    Replies:
    2
    Views:
    158
    Shea Martin
    Jun 22, 2006
  5. erdibalint
    Replies:
    0
    Views:
    108
    erdibalint
    Feb 20, 2008
Loading...

Share This Page