5

I have the following code

function myFunction(items) {
   // this prints out 11
   alert(items.length);

   $(items).each(function(i, item) {
       // item is undefined for some reason
   }
}

It I alert the length of items, it has elements in it (11 to be exact). so how could 11 items be present, but jQuery still pass undefined?

2
  • 5
    What's the value of $(this) inside of your .each() callback? Nothing looks incorrect so it would be helpful to see an SSCCE. Commented Jul 25, 2010 at 17:42
  • What is the type of items? is it an array or an array-like object like an HTMLCollection returned from .getElementsByClassName() for instance. Either way why not just use a standard for loop? Commented Jul 26, 2010 at 19:41

3 Answers 3

8

The only explanation for this is the that items array contains values which are undefined, i.e :

items = [undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined];

Both of the other answers are wholly incorrect. The first parameter of each is the index, not the value, and jQuery.fn.each calls jQuery.each. There is no disambiguation between them.

Sign up to request clarification or add additional context in comments.

3 Comments

Matt you are right. It was my code that made the mistake. I was using JSLINQ and I wrote my own implementation of Take(n). I was adding undefined objects to my array by mistake through a logic bug.
Old implementation is Take: function(count) { var retVal = new Array(); for (var index = 0; index < count; index++) retVal[retVal.length] = this.items[index]; return new JSLINQ(retVal); }
New one is Take: function(count) { var retVal = new Array(); for (var index = 0; index < Math.min(count, this.items.length); index++) retVal[retVal.length] = this.items[index]; return new JSLINQ(retVal); }
5

It sounds like you are not passing a jQuery wrappet set to your function. If you pass an array or an object you need to use the jQuery helper function $.each() like

$.each(items, function(index, element){
});

As I already mentioned several times in other answers, it is bad practice to loop over an array with .each() or javascripts native for..in.

If you are passing arrays use a standard for loop.

edit

As it turns out, you actually really can call the jQuery constructor with a standard array. But it seems like terrible karma to do so, you can't call 95% of all those jQuery methods, unless you want to crash / corrupt your code.

4 Comments

jAndy - An array will actually work the way OP has it (though I would agree that $.each() is better and for loop is best).
@patrick: Doh I wasn't exactly aware of that. What happens if you pass a standard array to the jQuery constructor and call like .animate() or whatoever on it?
jAndy - Seems to be catastrophic failure (unless of course it was an array of DOM elements). A good reason to not do it. But then again, when you think about it, that is what jQuery's .map() does. The callback returns some arbitrary value, which is placed into a jQuery object.
Animate will work against anything. For example: var foo = { x: 10, y: 12 }; $(foo).animate({ x: "+=20", y: "20" }, 1000, function () { alert(foo.x + ":" + foo.y); }); Will spit out "30:20". Is this useful? Perhaps not in everyday work. :) The trick with arrays is you'll set the same value across each entry. Example: var foo = [{ x: 10 }, { x: 20}]; $(foo).animate({ x: "+=30" }, 1000, function () { alert(this.x); }); Spits out "40" and "50".
0

Since comments don't allow pretty code listings ... (do they?):

Animate will work against anything. It's documented as only working against CSS properties, but just to prove a point:

var foo = { x: 10, y: 12 }; 

$(foo).animate({ x: "+=20", y: "20" }, 1000, 
      function () { alert(foo.x + ":" + foo.y); }); 

Will spit out "30:20". Is this useful? Perhaps not in everyday work. :)

The trick with arrays is you'll set the same property across each entry. Example:

var foo = [{ x: 10 }, { x: 20 }]; 

$(foo).animate({ x: "+=30" }, 1000, 
      function () { alert(this.x); }); 

Spits out "40" and "50".

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.