What is causing this 'Uncaught TypeError: Cannot call method 'animate' of undefined' error?
<p>All,</p>

<p>See the code below:</p>

<pre><code>function menu() {
    this.menuitem=[];
    this.submenu=[];
    this.menuitem[0] = $('div#sivname1');
    this.menuitem[1] = $('div#divname2');
    this.submenu[0] = $('div#submenu1');
    this.submenu[1] = $('div#submenu2');
    this.active = false;
    this.timeout;
}

menu.prototype = {
    animatedown: function(submenu) {
        submenu.animate({top: '99px'}, 200);
    },
    animateup: function(submenu) {
        submenu.animate({top: '-4px'}, 200);
    }
}

var menu = new menu();
z=2;
while(z--) {
    console.log(z);
    menu.menuitem[z].hover(
    function() { //mouseover
        if(menu.active) {
            clearTimeout(menu.submenu[z].data("timeout"));
        }
        else {
            menu.animatedown(menu.submenu[z])
        };
    },
    function() { //mouseleave
        $(this).data("timeout", setTimeout(function({
            menu.animateup(menu.submenu[z])
        },200));
        menu.active = false;    
    }),

    menu.submenu[z].hover(
    function() { //mouseover
        menu.active = true;
        if (menu.menuitem[z].data("timeout")) {
            clearTimeout(menu.menuitem[z].data("timeout"));
        };
    }, 
    function() { //mouseleave
        $(this).data("timeout", setTimeout(function() {
            menu.animateup(menu.submenu[z]);menu.active = false;
        },200));   
    });
}
</code></pre>

<p>This code gives the following error:</p>

<blockquote>
  <p>Uncaught TypeError: Cannot call method 'animate' of undefined</p>
</blockquote>

<p>And the strange this is that is I add:</p>

<pre><code>z=0; 
</code></pre>

<p>to the bottom of the code it will work properly. I would expect it to work without z=0 and I have no idea why it does when I add that. Can anyone please explain?</p>

<p>The problem was in the closures, the following code works:</p>

<pre><code>z=1;
while(z--){
  (function(z) {
    console.log(z);
      menu.menuitem[z].hover(
        function(){ //mouseover
          if(menu.active){clearTimeout(menu.submenu[z].data("timeout"));}
          else{menu.animatedown(menu.submenu[z])};
        }, 
        function(){ //mouseleave
          $(this).data("timeout", setTimeout(function(){menu.animateup(menu.submenu[z])},200));
          menu.active = false;    
        }
      )

      menu.submenu[z].hover(
        function(){ //mouseover
          menu.active = true;
          if(menu.menuitem[z].data("timeout")){clearTimeout(menu.menuitem[z].data("timeout"));};
        }, 
        function(){ //mouseleave
          $(this).data("timeout", setTimeout(function(){menu.animateup(menu.submenu[z]);menu.active = false;},200));   
        }
      );
  })(z); //this is to enable closures http://bonsaiden.github.com/JavaScript-Garden/#function.closures
}
</code></pre>
