2012-03-08 4 views
25

Underscore.js ha due modi di chiamare le funzioni, che chiamerò stile oggetto e stile di funzione. Oggetto stile è simile al seguente:Qual è il modo migliore di concatenare le funzioni di Underscore.js?

_(myObject).each(function (val, key) { 
    console.log(key, val); 
}); 

Funzione stile, d'altra parte, si presenta così:

_.each(myObject, function (val, key) { 
    console.log(key, val); 
}); 

ero felicemente utilizzando le chiamate agli oggetti in stile nel mio codice, ma ad un certo tuttavia, lo stile di chiamata dell'oggetto è scomparso dalla documentazione di underscore.js (sebbene le chiamate in stile oggetto funzionino perfettamente). Ho anche notato dei suggerimenti in giro (come nella documentazione di backbone.js) che lo stile di funzione è "migliore" o "preferito".

Quindi, lo stile di funzione è il metodo preferito? E se è così, qualcuno può spiegare il ragionamento alla base di questo?

Aggiornamento: @ggozad ha risposto parzialmente alla mia domanda. Ma sembra che la mia comprensione di come underscore.js funzioni è stata creata intorno alla versione 0.4.2. Leggendo la cronologia delle modifiche per underscore.js, si può vedere questa voce per la versione 1.2.4:

È ora possibile (e probabilmente dovrebbe) scrivere _.chain(list) invece di _(list).chain().

Mi piacerebbe sapere perché è necessario scrivere _.chain(list) anziché _(list).chain().

+0

'_ (list) .chain()' calcola internamente a qualcosa di simile a '_.chain (_ (list) .value())' con '_ (lista).value() === list'. Quindi chiamare '_.chain (list)' è più veloce – Tino

risposta

31

La risposta di @ggozad è in realtà molto fuorviante. Lo stile orientato agli oggetti non ha nulla a che fare con il concatenamento. L'esempio fornito:

_([1,2,3]).map(function (item) { return item * 2; }).map(function (item) { return item*3;}); 

in realtà non utilizza affatto il concatenamento di sottolineatura! Funziona solo perché l'oggetto array JS integrato ha la propria funzione map(). Prova una funzione che non è built-in (come shuffle) e vedrete si rompe:

_([1,2,3]).shuffle().shuffle(); 

L'unico modo per ottenere sottolineatura concatenamento è chiamare chain(), che si può fare utilizzando lo stile (OO o funzionale).

Per quanto riguarda il motivo per cui la documentazione dice che è necessario utilizzare _.chain, suppongo che sia solo una preferenza di stile. Ho aperto un issue at GitHub per chiarimenti.

+0

Solo pensieri: l'intera documentazione si basa sull'uso delle funzioni. Troverai la notazione orientata agli oggetti solo sotto la sezione di concatenamento e solo se saprai dove cercarla. E la differenza tra notazione orientata agli oggetti e chiamata _.chain è ancora facile da perdere. – Olga

+0

La risposta di ggozad è semplicemente ** sbagliata **. '_' non produrrà oggetti incatenabili a catena. Solo "_.chain" lo fa. '_.chain' non restituisce matrici né alcun oggetto JS nativo. Restituisce una monade e hai bisogno di una chiamata a 'value' per accedere al suo contenuto. –

+2

Vero che _() non incatena in underscore, ma fa catena in lodash. –

1

Quando _ viene utilizzato come funzione, esso essenzialmente avvolge l'argomento. Il wrapper fornisce tutte le funzioni di sottolineatura normale.

La differenza che distingue lo stile è che l'uso dello stile OOP (o dello stile oggetto nella definizione) è che produce oggetti avvolti su catena. Quindi è facile da fare:

_([1,2,3]).map(function (item) { return item * 2; }).map(function (item) { return item*3;}); 

L'equivalente sarebbe:

_.map(_.map([1,2,3], function (item) { return item * 2 }), function (item) { return item * 3 }); 

che è probabilmente meno chiaro.

+1

Grazie. Rileggendo la documentazione, è lì, ma è un po 'di confusione. Quindi, se questo è il caso, qual è il metodo preferito per il concatenamento? Si dovrebbe usare la funzione '_.chain()' o la chiamata in stile OOP? La cronologia delle modifiche dice "Ora puoi (e probabilmente dovresti) scrivere' _.chain (list) 'invece di' _ (list) .chain() '." ma non spiega perché. –

+0

Quando ho bisogno di catena preferisco lo stile OOP. Altrimenti rimango funzionale. Penso che sia una questione di stile e coerenza. – ggozad

+1

Il primo exampe dovrebbe leggere '_.chain ([1,2,3]). Map (function (item) {return item * 2;}). Map (function (item) {return item * 3;}). Value(); ', altrimenti è * non equivalente * al secondo esempio. – Tino