2012-06-19 11 views
6

Durante la lettura di jQuery Cookbook (Oreilly) la scorsa notte mi sono imbattuto in ogni funzione che produce una domanda che non riesco a trovare una risposta nel libro o online. Il codice che uso per questa domanda è situato jQuery site e ho compreso che qui di seguito come riferimento:

<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> 

Vorrei conoscere l'origine e lo scopo della 'i' parametro come non riesco a vedere dove viene da (codice cliente) e a cosa serve? Come un ragazzo di Java, riuscirò a cogliere il concetto molto più facilmente in quanto ho familiarità con il metodo o con i parametri di "funzione" nel contesto di Java.

Qui non vedo il codice client (presumo che sia nella libreria) e non vedo come (lo i) è rilevante nella funzione in quanto non è referenziato.

Qualcuno della comunità può dare una spiegazione chiara a questo o farmi fare riferimento a una guida al riguardo?

Comprendo lo scopo di ogni funzione e il riferimento "this" in modo da non doverli spiegare a meno che non lo riteniate rilevante per i futuri utenti di questa domanda.

risposta

13

In tal caso, non è stato necessario dichiarare lo i. La firma del each method è indicato nella documentazione di jQuery:

.each(function(index, Element))

Come si può vedere, ci vuole un argomento, e questo argomento è una funzione che prende 2 argomenti, index e Element.

Nel codice, i è un identificatore per index, che viene passato alla funzione di callback da jQuery ogni volta che viene chiamato (una volta per ogni iterazione). Passa anche un secondo argomento, ma non hai dichiarato un identificatore per esso, quindi sarà accessibile solo tramite l'oggetto arguments.

È possibile vedere esattamente quello che è passato alla callback accedendo che arguments oggetto:

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

Ecco un working example di quanto sopra.

Ecco il relevant code from jQuery itself (commenti aggiunti):

//... 
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; 
     } 
    } 
} 
+0

Quindi l'utilizzo dell'indice è nascosto in jQuery e non è necessario conoscere altro oltre a quello che dobbiamo fornire? – thejartender

+0

Sarà sempre passato alla funzione di callback da jQuery (così sarà l'argomento 'Element'). Se vuoi usarlo, aiuta a dargli un nome (come 'i' nel tuo esempio). Ho aggiunto la fonte pertinente di jQuery stessa, che potrebbe aiutare a spiegare ulteriormente. –

+0

Ti darei un voto in più per l'introduzione della funzione di registro. Aiuterà molto :) Grazie – thejartender

2

Quando si chiama $().each(), si passa una funzione di riferimento . Il modo in cui la funzione .each() funziona è che per ogni elemento nell'oggetto jQuery, chiama la funzione assegnata con l'elemento corrente come contesto (ad esempio all'interno della chiamata di funzione, la variabile this è l'elemento corrente).

Ora, quando jQuery chiama la funzione che gli hai fornito, lo può inoltrare gli argomenti opzionali allo, proprio come se si stesse chiamando una funzione nel codice. Con .each(), ogni volta che chiama la funzione assegnata, passa in due argomenti: un indice e l'elemento corrente .

E 'come se jQuery sta chiamando come:

$('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. 
} 

Potreste scoprire che the official documentation spiega meglio anche.

1

Come dice nell'API, l''i' è l'indice.

Questo potrebbe essere utile se si vuole fare una differenza tra il pari e gli elementi irregolari

come:

$(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 = ""; 
    } 
    }); 
}); 
1

' "origine" di questi parametri è "lascia essere diverso da prototype.js ".
Ha molto più senso passare i parametri nell'ordine opposto poiché l'indice è raramente necessario.

Considerate questo esempio:
che chiamano & funzione ha più senso?

$('.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! 
} 

Semplicemente riassunte qui:

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

$.each e $().each sia passaggio prima l'indice, e quindi il valore di callback. Ciò significa che se non ho bisogno dell'indice, non posso lasciare la dichiarazione della funzione come posso in Prototype.