Understanding origin of jQuery $each() parameters?

10,303

Solution 1

In that case, there was no need to declare the i. The signature of the each method is stated in the jQuery docs:

.each( function(index, Element) )

As you can see, it takes one argument, and that argument is a function that takes 2 arguments, index and Element.

In your code, i is an identifier for index, which is passed to the callback function by jQuery each time it is called (once for each iteration). It also passes a second argument, but you have not declared an identifier for it so it will only be accessible through the arguments object.

You can see exactly what is passed to the callback by logging that arguments object:

​$("div").each(function () { //No arguments listed in callback signature...
    console.log(arguments); //But arguments are still passed
});​​

Here's a working example of the above.

Here's the relevant code from jQuery itself (comments added):

//...
each: function( object, callback, args ) {
    //...

    //Iterate over the matched set of elements
    for ( ; i < length; ) {
        /* Call the callback in the context of the element, passing in the 
           index and the element */
        if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
            break;
        }
    }
}

Solution 2

When you call $().each(), you pass it a function reference. The way the .each() function works is that for each element in the jQuery object, it calls the function you gave it with the current element as the context (i.e. inside the function call, the this variable is the current element).

Now, when jQuery calls the function you gave it, it can pass in optional arguments, just as if you were calling a function in code. With .each(), whenever it calls the function you gave it, it passes in two arguments : an index and the current element.

It's as if jQuery is calling it like:

$('div').each(foo);

// results in something like
for(var i=0; i < $('div').length; i++) {

    // calling the foo function
    foo(i, $('div')[i]);

    // this is simplified, of course. 
    // this doesn't take into account the function context, or "this" variable.
}

You may find that the official documentation explains it better too.

Solution 3

The "origin" of these parameters is "lets be different from prototype.js."
It makes much more sense to pass the params in the opposite order as the index is seldom needed.

Consider this example:
which call & function makes the most sense?

$('.my-selector').each( modifyNodeA );
$('.my-selector').each( function(){
    // this wrapper anonymous function is cruft
    modifyNodeB(this);
});
$('.my-selector').each( modifyNodeB ); // this one won't work
$('.my-selector').each( modifyNodeC );
$('.my-selector').each( function(){
    // just using 'this' makes sense here.. it's evident that this is a jQuery closure
});

function modifyNodeA(i, node) {
    // this one works...  but gotta have i in the func signature.
    //   it won't be used and doesn't make contextual sense
    //  can also use 'this', but where the heck did it come from..  it's not evident
}

function modifyNodeB(node, i) {
    // 'i' could/should be an optional 2nd param
    //   this function could function on it's own
}

function modifyNodeC() {
    // gotta use the magic 'this' scope var..  where did it come from?
    // contextually, it would be nice to have the var passed... it is... as the 2nd param!
}

Simply summarized here:

Why I STILL prefer Prototype over jQuery - Section 8 - Other Nit-picks

$.each and $().each both pass first the index, and then the value to the callback. This means that if I have no need for the index, I can't just leave it off the function declaration like I can in Prototype.

Solution 4

As it says in the API the 'i' is the index.

That could be usefull if you want to make a difference between the even and uneven elements

Like:

$(document.body).click(function () {
  $("div").each(function (i) {            //Where does the 'i' come from?
    if (i % 2 == 0) {
      this.style.color = "blue";
    } else {
      this.style.color = "";
    }
  });
});
Share:
10,303
thejartender
Author by

thejartender

All you need to know about me is that I never give up. I learned Java programming from 2007 and took Vendor certifications. Unknowingly I had a brain tumor for many years before being diagnosed in 2010 with an orange-sized Anaplastic Astrocytoma. I endured 4 brain surgeries, 6 weeks chemo-radiotherapy and 10 months chemotherapy before getting back to what I love in 2012 when I launched http://thejarbar.org and http://buhaugane.com Oops 2012 and it happens again New tumor new surgery. Read about my life and support cancer (please) http://www.news24.com/MyNews24/Lack-of-brain-cancer-awareness-cost-me-Astrocytoma-20121011 AGAIN!! 2013 and diagnosed with my third tumor in as many years only more aggressive. Never giving up :)

Updated on June 23, 2022

Comments

  • thejartender
    thejartender almost 2 years

    Whilst reading jQuery Cookbook (Oreilly) last night I came across an each function that produces a question that I can't seem to find an answer in the book for, or online. The code I use for this question is found from jQuery site and I included it below as a reference:

    <script>
        $(document.body).click(function () {
          $("div").each(function (i) {            //Where does the 'i' come from?
            if (this.style.color != "blue") {
              this.style.color = "blue";
            } else {
              this.style.color = "";
            }
          });
        });
    </script>
    

    I would like to know the origin and purpose of the 'i' parameter as I fail to see where it comes from (client code) and what it is used for? As a Java guy I will grasp the concept a lot easier as I familiar with method or 'function' params in the context of Java.

    Here I don't see the client code (I presume it's in the library) and I don't see how it (the i) is relevant in the function as it's not referenced.

    Can someone from the community give a clear explanation for this or refer me to a guide on this?

    I understand the purpose of the each function and the 'this' reference so you don't need to explain these unless you feel it relevant to future viewers of this question.