Qual è il contesto in _.each (elenco, iteratore, )?

Sono nuovo di underscore.js. Qual è lo scopo di [context] in _.each() ? Come dovrebbe essere usato?

Il parametro context imposta semplicemente il valore di this nella funzione iteratore.

 var someOtherArray = ["name","patrick","d","w"]; _.each([1, 2, 3], function(num) { // In here, "this" refers to the same Array as "someOtherArray" alert( this[num] ); // num is the value from the array being iterated // so this[num] gets the item at the "num" index of // someOtherArray. }, someOtherArray); 

Esempio di lavoro: http://jsfiddle.net/a6Rx4/

Usa il numero di ciascun membro dell’array che viene iterato per ottenere l’elemento in quell’indice di someOtherArray , che è rappresentato da this dato che lo abbiamo passato come parametro di contesto.

Se non si imposta il contesto, this si riferirà all’object della window .

context è dove this riferisce alla funzione iteratore. Per esempio:

 var person = {}; person.friends = { name1: true, name2: false, name3: true, name4: true }; _.each(['name4', 'name2'], function(name){ // this refers to the friends property of the person object alert(this[name]); }, person.friends); 

Il contesto consente di fornire argomenti al momento della chiamata, consentendo una facile personalizzazione delle funzioni di supporto predefinite generiche.

qualche esempio:

 // stock footage: function addTo(x){ "use strict"; return x + this; } function pluck(x){ "use strict"; return x[this]; } function lt(x){ "use strict"; return x < this; } // production: var r = [1,2,3,4,5,6,7,8,9]; var words = "a man a plan a canal panama".split(" "); // filtering numbers: _.filter(r, lt, 5); // elements less than 5 _.filter(r, lt, 3); // elements less than 3 // add 100 to the elements: _.map(r, addTo, 100); // encode eggy peggy: _.map(words, addTo, "egg").join(" "); // get length of words: _.map(words, pluck, "length"); // find words starting with "e" or sooner: _.filter(words, lt, "e"); // find all words with 3 or more chars: _.filter(words, pluck, 2); 

Anche dagli esempi limitati, puoi vedere quanto sia potente un "argomento extra" per creare codice riutilizzabile. Invece di creare una funzione di callback diversa per ogni situazione, di solito è ansible adattare un helper di basso livello. L'objective è quello di avere la logica personalizzata che raggruppa un verbo e due nomi, con un numero minimo di caratteri.

Certo, le funzioni freccia hanno eliminato molti dei vantaggi del "codice golf" delle funzioni pure generiche, ma i vantaggi semantici e di coerenza rimangono.

Aggiungo sempre "use strict" agli helper per fornire la compatibilità nativa [].map() quando si passano le primitive. Altrimenti, vengono forzati in oggetti, che di solito funzionano ancora, ma è più veloce e più sicuro essere specifici del tipo.

Come spiegato in altre risposte, context è il contesto da utilizzare all’interno del callback passato a each .

Lo spiegherò con l’aiuto del codice sorgente dei metodi rilevanti dal codice sorgente di sottolineatura

La definizione di _.each o _.forEach è la seguente:

 _.each = _.forEach = function(obj, iteratee, context) { iteratee = optimizeCb(iteratee, context); var i, length; if (isArrayLike(obj)) { for (i = 0, length = obj.length; i < length; i++) { iteratee(obj[i], i, obj); } } else { var keys = _.keys(obj); for (i = 0, length = keys.length; i < length; i++) { iteratee(obj[keys[i]], keys[i], obj); } } return obj; }; 

Seconda affermazione è importante notare qui

 iteratee = optimizeCb(iteratee, context); 

Qui, il context viene passato a un altro metodo optimizeCb e la funzione restituita da esso viene quindi assegnata a iteratee che viene chiamata in seguito.

 var optimizeCb = function(func, context, argCount) { if (context === void 0) return func; switch (argCount == null ? 3 : argCount) { case 1: return function(value) { return func.call(context, value); }; case 2: return function(value, other) { return func.call(context, value, other); }; case 3: return function(value, index, collection) { return func.call(context, value, index, collection); }; case 4: return function(accumulator, value, index, collection) { return func.call(context, accumulator, value, index, collection); }; } return function() { return func.apply(context, arguments); }; }; 

Come si può vedere dalla precedente definizione del metodo di optimizeCb , se il context non viene passato, func viene restituito così com'è. Se viene passato il context , la funzione di callback viene chiamata come

 func.call(context, other_parameters); ^^^^^^^ 

func viene chiamato con call() che viene usato per invocare un metodo impostandone il contesto. Quindi, quando this è usato all'interno di func , farà riferimento al context .

 // Without `context` _.each([1], function() { console.log(this instanceof Window); }); // With `context` as `arr` var arr = [1, 2, 3]; _.each([1], function() { console.log(this); }, arr); 
  

Uso semplice di _.each

 _.each(['Hello', 'World!'], function(word){ console.log(word); });