Differenze tra lodash e underscore [chiuso]


1602

Perché qualcuno dovrebbe preferire la libreria di utilità lodash.js o underscore.js rispetto all'altra?

Lodash sembra essere un rimpiazzo per il carattere di sottolineatura, quest'ultimo essendo in circolazione da più tempo.

Penso che entrambi siano geniali, ma non so abbastanza su come funzionano per fare un confronto educato, e vorrei sapere di più sulle differenze.


2
Potresti dare un'occhiata ad alcuni dei cast dello schermo su lodash che sono collegati alla sua pagina github. Personalmente sto usando underscore.js, ma di più perché è quello che ho iniziato e come dici che è in circolazione da più tempo.
Jack,

26
lodashe underscoresono ora sotto thread di unione
zangw,

Risposte:


2023

Ho creato Lo-Dash per fornire un supporto iterativo cross-environment più coerente per array, stringhe, oggetti e argumentsoggetti 1 . Da allora è diventato un superset di Underscore, fornendo un comportamento API più coerente, più funzionalità (come supporto AMD, clone profondo e fusione profonda), documentazione più approfondita e test unitari (test eseguiti su Node, Ringo, Rhino, Narwhal, PhantomJS e browser), migliori prestazioni complessive e ottimizzazioni per array di grandi dimensioni / iterazione di oggetti e maggiore flessibilità con build personalizzate e utilità di pre-compilazione di modelli.

Poiché Lo-Dash viene aggiornato più frequentemente di Underscore, viene fornita una lodash underscorebuild per garantire la compatibilità con l'ultima versione stabile di Underscore.

Ad un certo punto mi è stato persino concesso l' accesso push a Underscore, in parte perché Lo-Dash è responsabile per sollevare più di 30 problemi; correzioni di bug di atterraggio, nuove funzionalità e guadagni perf in Underscore v1.4.x +.

Inoltre ci sono almeno 3 piastre backbone che includono Lo-Dash per impostazione predefinita e Lo-Dash è ora menzionato nella documentazione ufficiale di Backbone .

Dai un'occhiata al post di Kit Cambridge, Dì "Ciao" a Lo-Dash , per un'analisi più approfondita delle differenze tra Lo-Dash e Underscore.

Note:

  1. Underscore ha un supporto incoerente per array, stringhe, oggetti e argumentsoggetti. Nei browser più recenti, i metodi Underscore ignorano i buchi negli array , i metodi "Oggetti" ripetono gli argumentsoggetti, le stringhe vengono trattate come matrici e i metodi eseguono correttamente le funzioni (ignorando la loro proprietà "prototipo") e gli oggetti (ripetendo le proprietà ombreggiate come "toString" e "valueOf"), mentre nei browser meno recenti non lo faranno. Inoltre, i metodi Underscore come _.clonepreservare i buchi negli array, mentre ad altri _.flattennon piace .

174
@Brian - Durante lo sviluppo di Lo-Dash ho continuato a porre la domanda "Cosa potrebbe indicare qualcuno, a Lo-Dash, come negativo rispetto a Underscore?" e poi affrontarli. Questo è il motivo per cui ho rinforzato la documentazione, aggiunto build personalizzate e reso la fonte più leggibile.
John-David Dalton,

10
Sono molto tentato di pubblicare alcuni benchmark, ma questo potrebbe diventare noioso. Basti dire che ogni benchmark che ho eseguito ha dimostrato che Lo-Dash è più veloce ( MOLTO più veloce in molti casi) del carattere di sottolineatura.
Wil Moore III,

186
Adoro lo-dash e lo sto usando, quindi per favore non pensare che stia colpendo, ma perché non contribuire a sottolineare invece di creare una nuova libreria?
Xananax,

133
@Xananax - controlla il thread dei commenti: github.com/jashkenas/underscore/commit/… - questo potrebbe rispondere a questa domanda.
Rob Grant,

41
C'è stato qualche sforzo per ricollegare lodash al carattere di sottolineatura?
lampione

186

Lo-Dash si ispira alla sottolineatura, ma al giorno d'oggi è una soluzione superiore. Puoi creare le tue build personalizzate , avere prestazioni più elevate , supportare AMD e avere straordinarie funzionalità extra . Controllare questo Lo-Dash vs benchmark sottolineatura sulla jsperf e .. questo impressionante post su lo-dash :

Una delle funzionalità più utili quando si lavora con le raccolte è la sintassi abbreviata:

var characters = [
  { 'name': 'barney', 'age': 36, 'blocked': false },
  { 'name': 'fred',   'age': 40, 'blocked': true }
];

// using "_.filter" callback shorthand
_.filter(characters, { 'age': 36 });

// using underscore
_.filter(characters, function(character) { return character.age === 36; } );

// → [{ 'name': 'barney', 'age': 36, 'blocked': false }]

(tratto da documenti lodash )


1
Il link al blog di Kit Cambridge è molto istruttivo.
Brian M. Hunt,

Penso che sia sbagliato (l'esempio spennato). A partire dall'ultimo aggiornamento 1.8.3, puoi usare pluck allo stesso modo di lodash. comunque per le versioni precedenti non credo che il carattere di sottolineatura esporrebbe una funzione che è la stessa di una mappa (il tuo esempio di trattino basso sembra una funzione di mappa)
alexserver,

7
filterfunzione di sottolineatura del 2012 github.com/jashkenas/underscore/issues/648 (il suo nome è where)
Muhammad Hewedy

Ricevo l'errore 500 sul link benchmark Lo-Dash vs Underscore
Hylle

86

Se come me ti aspettavi un elenco di differenze d'uso tra underscore e lodash, c'è una guida per la migrazione da underscore a lodash .

Ecco lo stato attuale per i posteri:

  • Underscore _.anyè Lodash_.some
  • Underscore _.allè Lodash_.every
  • Underscore _.composeè Lodash_.flowRight
  • Underscore _.containsè Lodash_.includes
  • Underscore _.eachnon consente di uscire tornandofalse
  • Underscore _.findWhereè Lodash_.find
  • Underscore _.flattenè profondo per impostazione predefinita mentre Lodash è superficiale
  • Underscore _.groupBysupporta un iteratee che viene passato i parametri (value, index, originalArray), mentre in Lodash, l'iteratee per _.groupByviene passato un solo parametro: (value).
  • Il trattino basso _.indexOfcon il 3o parametro undefinedè Lodash_.indexOf
  • Il trattino basso _.indexOfcon il 3o parametro trueè Lodash_.sortedIndexOf
  • Underscore _.indexByè Lodash_.keyBy
  • Underscore _.invokeè Lodash_.invokeMap
  • Underscore _.mapObjectè Lodash_.mapValues
  • Underscore _.maxcombina Lodash_.max&_.maxBy
  • Underscore _.mincombina Lodash _.min&_.minBy
  • Underscore _.samplecombina Lodash _.sample&_.sampleSize
  • Underscore _.objectcombina Lodash _.fromPairse_.zipObject
  • La sottolineatura _.omitdi un predicato è Lodash_.omitBy
  • Underscore _.pairsè Lodash_.toPairs
  • La sottolineatura _.pickdi un predicato è Lodash_.pickBy
  • Underscore _.pluckè Lodash_.map
  • Underscore _.sortedIndexcombina Lodash _.sortedIndex&_.sortedIndexOf
  • Sottolineatura _.uniqdi un iterateeè Lodash_.uniqBy
  • Underscore _.whereè Lodash_.filter
  • Underscore _.isFinitenon si allinea con Number.isFinite
    (es. _.isFinite('1')Ritorna truein Underscore ma falsein Lodash)
  • La _.matchesstenografia di Underscore non supporta confronti approfonditi
    (ad es. _.filter(objects, { 'a': { 'b': 'c' } }))
  • Underscore ≥ 1.7 e _.templatesintassi di Lodash è
    _.template(string, option)(data)
  • Le _.memoizecache di Lodash sono Mapcome oggetti
  • Lodash non supporta un contextargomento per molti metodi a favore di_.bind
  • Lodash supporta il concatenamento implicito , concatenamento pigro e la fusione rapida
  • Lodash diviso sua sovraccarico _.head, _.last, _.rest, e _.initialfuori nella
    _.take, _.takeRight, _.drop, e _.dropRight
    (cioè _.head(array, 2)in sottolineatura è _.take(array, 2)in Lodash)

1
Mi sono imbattuto in questi problemi durante la migrazione e sto mantenendo una documentazione incrociata (WIP) tra l'uno e l'altro. Spero che sia utile anche ad altre persone!
luxon

60

Oltre alla risposta di John e alla lettura di lodash (che fino a quel momento avevo considerato un "me-troppo" da sottolineare), e vedendo i test delle prestazioni, leggendo il codice sorgente e i post sul blog , i pochi punti che rendono lodash molto superiori alla sottolineatura sono questi:

  1. Non si tratta della velocità, in quanto si tratta della coerenza della velocità (?)

    Se si esamina il codice sorgente del carattere di sottolineatura, nelle prime righe si noterà che il carattere di sottolineatura ricade sulle implementazioni native di molte funzioni. Sebbene in un mondo ideale, questo sarebbe stato un approccio migliore, se si considerassero alcuni dei collegamenti perf forniti in queste diapositive , non è difficile trarre la conclusione che la qualità di quelle "implementazioni native" varia molto dal browser- to-browser. Firefox è dannatamente veloce in alcune delle funzioni e in alcune Chrome domina. (Immagino che ci sarebbero alcuni scenari in cui anche IE dominerebbe). Credo che sia meglio preferire un codice le cui prestazioni siano più coerenti tra i browser.

    Leggi il post sul blog in precedenza e, invece di crederlo per il suo bene, giudica tu stesso eseguendo i benchmark . Sto stordito in questo momento, vedendo un lodash eseguendo 100-150% più veloce di sottolineatura in anche semplice , nativo funzioni quali Array.everyin Chrome!

  2. Gli extra in lodash sono anche abbastanza utili.

  3. Per quanto riguarda il commento altamente votato di Xananax che suggerisce un contributo al codice di sottolineatura: è sempre meglio avere una buona concorrenza, non solo fa andare avanti l'innovazione, ma ti spinge anche a mantenere te stesso (o la tua biblioteca) in buona forma.

Ecco un elenco di differenze tra lodash e la sua sottolineatura-build sostituisce i tuoi progetti di sottolineatura.


6
In quale caso la "coerenza della velocità" è un valore? Diciamo, ho un metodo che ha una velocità del 100% in FF e in IE e un'implementazione nativa avrebbe una velocità dell'80% in IE e del 120% in FF (o viceversa). Quindi direi che sarebbe bene usare l'implementazione nativa in FF e la propria implementazione in IE. Non riesco a immaginare nessun caso, dove direi: rallentiamo FF solo per il motivo di avere la stessa velocità lì come in IE. Dimensioni del codice e manutenibilità o un rallentamento medio in tutti i browser sarebbero argomenti, ma coerenza di velocità?
Stofl

2
Intendevo "velocità sempre più veloce"
kumarharsh,

1
Che dire della differenza di dimensioni? Diciamo che crei una build personalizzata con lodash che abbia esattamente le stesse funzionalità di underscore? C'è una grande differenza tra loro? Immagino che la reimplementazione aggiunga peso al sito.
F Lekschas,

5
Sono propenso al fallback dell'implementazione nativa del browser semplicemente perché nella maggior parte dei casi ha prestazioni accettabili e può migliorare con gli aggiornamenti del browser senza preoccuparsi di mantenere la libreria aggiornata.
orad,

3
@KumarHarsh Forse non l'ho detto bene. Volevo dire che sono propenso a utilizzare una libreria che utilizza internamente funzioni native se disponibili, anziché preferire sempre la propria implementazione.
Orad,

42

Questo è il 2014 e un paio d'anni in ritardo. Penso ancora che il mio punto valga:

IMHO questa discussione è stata sproporzionata abbastanza. Citando il suddetto post sul blog :

La maggior parte delle librerie di utilità JavaScript, come Underscore, Valentine e wu, si basano sul "doppio approccio nativo". Questo approccio preferisce le implementazioni native, tornando a JavaScript vanilla solo se l'equivalente nativo non è supportato. Ma jsPerf ha rivelato una tendenza interessante: il modo più efficiente di scorrere su una raccolta array o simile a una matrice è evitare completamente le implementazioni native, optando invece per semplici loop.

Come se "semplici loop" e "vanilla Javascript" siano più nativi delle implementazioni del metodo Array o Object. Accidenti ...

Sarebbe certamente bello avere un'unica fonte di verità, ma non lo è. Anche se ti è stato detto diversamente, non c'è Dio alla vaniglia, mio ​​caro. Mi dispiace. L'unico presupposto che vale davvero è che stiamo tutti scrivendo codice Javascript che mira a funzionare bene in tutti i principali browser, sapendo che tutti hanno implementazioni diverse delle stesse cose. È una stronza da affrontare, per dirla in modo lieve. Ma questa è la premessa, che ti piaccia o no.

Forse state lavorando a progetti su larga scala che necessitano di prestazioni ottimistiche in modo da vedere davvero la differenza tra 850.000 (trattino basso) e 2.500.000 (lodash) iterazioni su un elenco al secondo in questo momento!

Io per primo non lo sono. Voglio dire, ho lavorato a progetti in cui dovevo affrontare problemi di performance, ma non sono mai stati risolti o causati da Underscore o Lo-Dash. E a meno che non riesca a comprendere le reali differenze nell'implementazione e nelle prestazioni (stiamo parlando C ++ in questo momento) di diciamo un ciclo su un iterabile (oggetto o array, scarso o no!), Preferisco non preoccuparmi di alcun affermazioni basate sui risultati di una piattaforma di benchmark già considerata .

Ha solo bisogno di un singolo aggiornamento di diciamo a Rhino di dare fuoco alle sue implementazioni del metodo Array in un modo che non un singolo "metodo del ciclo medievale funziona meglio e per sempre e quant'altro" il sacerdote può discutere il suo semplice fatto che tutti un improvviso metodo di array in FF è molto più veloce del suo cervello immaginato. Amico, non puoi semplicemente imbrogliare il tuo ambiente di runtime truffando il tuo ambiente di runtime! Pensaci quando promuovi ...

la tua cintura di utilità

... la prossima volta.

Quindi, per mantenerlo rilevante:

  • Usa Underscore se sei a tuo agio senza sacrificare l'ish nativo.
  • Usa Lo-Dash se sei a tuo agio e ti piace il suo catalogo di funzioni estese (copia profonda ecc.) E se hai un disperato bisogno di prestazioni istantanee e, soprattutto, non ti dispiace accontentarti di un'alternativa non appena il outshine dell'API nativa workauround supponente. Che succederà presto. Periodo.
  • C'è anche una terza soluzione. FAI DA TE! Conosci i tuoi ambienti. Conoscere le incongruenze. Leggi il loro codice ( John-David e Jeremy ). Non utilizzare questo o quello senza essere in grado di spiegare perché un livello di coerenza / compatibilità è davvero necessario e migliora il flusso di lavoro o migliora le prestazioni della tua app. È molto probabile che le tue esigenze siano soddisfatte con un semplice polyfill che sei perfettamente in grado di scrivere da solo. Entrambe le biblioteche sono semplicemente vaniglia con un po 'di zucchero. Entrambi litigano per chi sta servendo la torta più dolce . Ma credimi, alla fine entrambi cucinano solo con acqua. Non c'è Dio alla vaniglia, quindi non può esserci papa alla vaniglia, giusto?

Scegli l'approccio più adatto alle tue esigenze. Come di solito. Preferirei i fallback sulle implementazioni effettive rispetto ai cheat di runtime presunti in qualsiasi momento, ma anche oggi sembra essere una questione di gusti. Attenersi a risorse di qualità come http://developer.mozilla.com e http://caniuse.com e andrà tutto bene.


Grazie per aver pubblicato Lukas. I built-in possono essere ulteriormente ottimizzati? Ho raccolto che hanno dei vincoli imposti dagli standard che impediscono loro di avere ottimizzazioni paragonabili alle librerie, ma non conosco i dettagli in maniera diretta o se ciò fosse o rimanga vero.
Brian M. Hunt,

ad esempio "Ottimizzando per il caso d'uso del 99%, i metodi fast.js possono essere fino a 5 volte più veloci dei loro equivalenti nativi." - github.com/codemix/fast.js
Brian M. Hunt,

1
Ciao Brian, mi dispiace che sia stato fuorviante, non intendevo dire che quelle librerie non sono molto più veloci dei loro equivalenti nativi. Se hai un disperato bisogno di prestazioni in questo momento , probabilmente stai meglio con un toolkit come LoDash o fast.js in quanto forniscono implementazioni più rapide di metodi standard. Ma se si sceglie di utilizzare una libreria che non si basa su metodi nativi, è possibile che si perda qualsiasi futura ottimizzazione delle prestazioni sui built-in. I browser alla fine si evolveranno.
Lukas Bünger,

4
I "produttori" dei browser fanno fatica a mantenere gli standard dei loro browser conformi, molto meno performanti. La maggior parte dei miglioramenti delle prestazioni nelle implementazioni native sono il risultato di un hardware più veloce. La scusa "le implementazioni native recupereranno" esiste da anni. Anni = eternità su Internet. Se le implementazioni native verranno mai raggiunte, le librerie verranno aggiornate per usarle. Questa è la cosa bella dell'open source. Se uno sviluppatore di app non si aggiorna all'ultima libreria, la sua app non rallenterà improvvisamente, semplicemente non accelererà.
Andrew Steitz,

2
... ma se Array.fromglielo chiedessi, probabilmente non saprebbero nemmeno cosa dovrebbe fare. Le persone della "cintura di utilità" di JS sembrano essere così eccessivamente preoccupate di promuovere le loro soluzioni così geniali che tendono a dimenticare che, così facendo, stanno effettivamente diluendo il processo di standardizzazione. Nessuna necessità di funzionalità non comporta alcuna pressione sui "produttori" del browser. Curiosità: 2 dei 4 principali browser sono basati su progetti open source ( 1 , 2 ).
Lukas Bünger,

20

Sono d'accordo con la maggior parte delle cose dette qui, ma voglio solo sottolineare un argomento a favore di underscore.js: la dimensione della libreria.

Soprattutto nel caso in cui si stia sviluppando un'app o un sito Web che intende essere utilizzato principalmente su dispositivi mobili, la dimensione del pacchetto risultante e l'effetto sul tempo di avvio o download potrebbero avere un ruolo importante.

Per fare un confronto, queste dimensioni sono quelle che ho notato con source-map-explorer dopo aver eseguito il servizio ionico:

lodash: 523kB
underscore.js: 51.6kb

modificato febbraio 2020 :

si può usare BundlePhobia per verificare le dimensioni correnti di Lo-Dash e Underscore


1
Grazie Peter, questo è un punto degno di nota qui. C'è altro dibattito altrove, tra cui: gist.github.com/alekseykulikov/5f4a6ca69e7b4ebed726 . (Questa risposta potrebbe essere migliorata collegando alcune delle altre discussioni e citando i bit pertinenti). La differenza di dimensioni può essere ridotta scegliendo sottosezioni di lodash, oltre a lodash che scuotono gli alberi. 🕷
Brian M. Hunt,

Thx @ BrianM.Hunt for your reply, non sapevo che fosse possibile includere sottosezioni di lodash, daremo un'occhiata. Recentemente con ionico nativo, Ionic ha intrapreso un percorso simile anche per le sue librerie native, bene notare che più si preoccupano maggiormente delle dimensioni dell'app
David Dal Busco,

1
mi chiedo dove hai preso i 523kB? lodash.com afferma che è compresso solo 24kB. il download è solo 74kB
Martian2049

1
il mio post è stato pubblicato ad aprile 2017. come ho detto nel mio commento,source-map-explorer after running ionic serve
David Dal Busco,

5
Nel marzo 2018 - lodash.min.js è 72,5 kB e underscore-min.js è 16,4 kB
Combina il

10

Non sono sicuro se questo è ciò che significava OP, ma mi sono imbattuto in questa domanda perché stavo cercando un elenco di problemi che devo tenere a mente durante la migrazione da trattino basso a lodash.

Gradirei davvero se qualcuno pubblicasse un articolo con un elenco completo di tali differenze. Vorrei iniziare con le cose che ho imparato a mie spese (vale a dire, cose che hanno fatto esplodere il mio codice durante la produzione: /):

  • _.flattenin underscore è profondo di default e devi passare true come secondo argomento per renderlo superficiale. In lodash è superficiale per impostazione predefinita e passare vero come secondo argomento lo renderà profondo! :)
  • _.lastin underscore accetta un secondo argomento che dice quanti elementi vuoi. In lodashnon esiste tale opzione. Puoi emularlo con.slice
  • _.first (stesso problema)
  • _.templatenel carattere di sottolineatura può essere utilizzato in molti modi, uno dei quali è fornire la stringa e i dati del modello e HTMLtornare indietro (o almeno è così che funzionava qualche tempo fa). Inlodash si riceve una funzione che è quindi necessario alimentare con i dati.
  • _(something).map(foo)funziona in underscore, ma in lodash ho dovuto riscriverlo _.map(something,foo). Forse era solo un TypeScriptproblema

4
In lodash, il concatenamento passa un iteratore pigro e richiede ed endpoint simili _(something).map(foo).value().
Brian M. Hunt

Tutto ciò può colpirti se usi Backbone Collection che invia proxy a queste librerie - ad esempio collection.first (5) non ti darà i primi 5 elementi, ma piuttosto il primo :)
qbolec

8

http://benmccormick.org/2014/11/12/underscore-vs-lodash/

Ultimo articolo che confronta i due di Ben McCormick:

  1. L'API di Lo-Dash è un superset di Underscore.

  2. Under the hood [Lo-Dash] è stato completamente riscritto.

  3. Lo-Dash non è sicuramente più lento di Underscore.

  4. Cosa ha aggiunto Lo-Dash?

    • Miglioramenti dell'usabilità
    • Funzionalità extra
    • Guadagni prestazionali
    • Sintassi di stenografia per il concatenamento
    • Build personalizzati per utilizzare solo ciò di cui hai bisogno
    • Versione semantica e copertura del codice al 100%

6

Ho appena trovato una differenza che è diventata importante per me. La versione non compatibile del carattere di sottolineatura _.extend()non lo è copiare più di proprietà o metodi di classe a livello definita.

Ho creato un test Jasmine in CoffeeScript che lo dimostra:

https://gist.github.com/softcraft-development/1c3964402b099893bd61

Fortunatamente, lodash.underscore.jsconserva il comportamento di Underscore nel copiare tutto, che per la mia situazione era il comportamento desiderato.


4

lodash ha ottenuto _.mapValues()che è identico a quello di underescore _.mapObject().


0

Per la maggior parte il carattere di sottolineatura è un sottoinsieme di lodash. A volte, come la sottolineatura al momento, avrà piccole funzioni interessanti, lodash non ha come mapObject. Questo mi ha fatto risparmiare un sacco di tempo nello sviluppo del mio progetto.


al momento, abbiamo _.mapValues
crapthings il

@crapthings - al momento di questo post conoscevo mayValues ​​e mapKeys ma non sono gli stessi di mapObject. Forse ci sono casi da applicare l'uno sull'altro ma mapObject è una funzione a sé stante.
rashadb,

0

Sono abbastanza simili, con Lodash sta subentrando ...

Entrambi sono una libreria di utilità che porta il mondo dell'utilità in JavaScript ...

Sembra che Lodash venga aggiornato più regolarmente ora, quindi più utilizzato negli ultimi progetti ...

Anche Lodash sembra essere più leggero di un paio di KB ...

Entrambi hanno una buona API e doc, ma penso che Lodash uno sia meglio ...

Ecco uno screenshot per ciascuno dei documenti per ottenere il primo valore di un array ...

sottolineare:

sottolineare

lodash: lodash

Poiché le cose potrebbero essere aggiornate di volta in volta, basta controllare anche il loro sito Web ...

lodash

sottolineare

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.