Diferenças entre lodash e sublinhado [fechado]

1602

Por que alguém prefere a biblioteca de utilitários lodash.js ou underscore.js em detrimento da outra?

Lodash parece ser um substituto para o sublinhado, este último há mais tempo.

Penso que ambos são brilhantes, mas não sei o suficiente sobre como eles funcionam para fazer uma comparação educada e gostaria de saber mais sobre as diferenças.

Brian M. Hunt
fonte
2
Você pode dar uma olhada em algumas transmissões de tela sobre lodash às quais há links na página do github. Pessoalmente, tenho usado o underscore.js, mas mais porque foi com isso que eu comecei e, como você diz, já existe há mais tempo.
12123 Jack
26
lodashe underscoreestão sob rosca merge agora
zangw

Respostas:

2023

Criei o Lo-Dash para fornecer suporte de iteração entre ambientes mais consistente para matrizes, seqüências de caracteres, objetos e argumentsobjetos 1 . Desde então, tornou-se um superconjunto do Underscore, fornecendo um comportamento de API mais consistente, mais recursos (como suporte AMD, clone profundo e mesclagem profunda), documentação mais completa e testes de unidade (testes executados em Node, Ringo, Rhino, Narwhal, PhantomJS e navegadores), melhor desempenho geral e otimizações para matrizes grandes / iteração de objetos e mais flexibilidade com construções personalizadas e utilitários de pré-compilação de modelos.

Como o Lo-Dash é atualizado com mais frequência que o Underscore, é fornecida uma lodash underscorecompilação para garantir a compatibilidade com a versão estável mais recente do Underscore.

A certa altura, recebi até acesso push ao Underscore, em parte porque Lo-Dash é responsável por levantar mais de 30 questões; correções de erros de aterrissagem, novos recursos e ganhos de desempenho no Underscore v1.4.x +.

Além disso, existem pelo menos três boilerplates do Backbone que incluem Lo-Dash por padrão e o Lo-Dash agora é mencionado na documentação oficial do Backbone .

Confira o post de Kit Cambridge, Diga "Olá" a Lo-Dash , para uma análise mais profunda das diferenças entre Lo-Dash e Underscore.

Notas de rodapé:

  1. O sublinhado possui suporte inconsistente para matrizes, seqüências de caracteres, objetos e argumentsobjetos. Nos navegadores mais recentes, os métodos de sublinhado ignoram os buracos nas matrizes , os métodos "Objetos" iteram argumentsobjetos, as seqüências de caracteres são tratadas como matrizes e os métodos iteram corretamente as funções (ignorando sua propriedade "prototype") e os objetos (iterando propriedades sombreadas como "toString" e "valueOf"), enquanto em navegadores mais antigos eles não o fazem. Além disso, os métodos de sublinhado, como _.clonepreservar orifícios nas matrizes, enquanto outros, como _.flattennão.
John-David Dalton
fonte
174
@Brian - Enquanto desenvolvia o Lo-Dash, continuei fazendo a pergunta "O que alguém poderia apontar, no Lo-Dash, como negativo em comparação com o Underscore?" e depois resolvê-los. É por isso que aprimorei a documentação, adicionei construções personalizadas e tornei a fonte mais legível.
John-David Dalton
10
Estou muito tentado a publicar alguns benchmarks, mas isso pode se tornar tedioso. Basta dizer que todas as referências que corri demonstraram que o Lo-Dash é mais rápido ( MUITO mais rápido em muitos casos) do que o sublinhado.
Wil Moore III
186
Eu amo lo-dash e estou usando, então, por favor, não pense que estou me contorcendo, mas por que não contribuir para sublinhar em vez de criar uma nova biblioteca?
Xananax
133
@Xananax - verifique o tópico de comentários: github.com/jashkenas/underscore/commit/… - isso pode responder a essa pergunta.
Rob Grant
41
Houve algum esforço para juntar o lodash de volta ao sublinhado?
Streetlight
186

Lo-Dash é inspirado em sublinhado, mas hoje em dia é uma solução superior. Você pode criar suas construções personalizadas , ter um desempenho mais alto , dar suporte à AMD e ter ótimos recursos extras . Confira estes benchmarks Lo-Dash vs Underscore no jsperf e .. este post incrível sobre lo-dash :

Um dos recursos mais úteis quando você trabalha com coleções é a sintaxe abreviada:

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

(extraído de documentos do lodash )

neiker
fonte
1
O link para o blog de Kit Cambridge é muito informativo.
Brian M. Caça
Eu acho que isso está errado (o exemplo de arrancar). Desde a última atualização 1.8.3, você pode usar o arranque da mesma maneira que o lodash. de qualquer maneira para versões anteriores eu não acho sublinhado exporia uma função que é o mesmo mapa a (o seu exemplo sublinhado parece ser uma função de mapa)
alexserver
7
filterrecurso no sublinhado a partir de 2012 github.com/jashkenas/underscore/issues/648 (seu nome é where)
Muhammad Hewedy
Estou recebendo o erro 500 no link de benchmark Lo-Dash vs Underscore
Hylle 7/19/19
86

Se, como eu, você esperava uma lista de diferenças de uso entre sublinhado e lodash, há um guia para migrar de sublinhado para lodash .

Aqui está o estado atual da posteridade:

  • Sublinhado _.anyé Lodash_.some
  • Sublinhado _.allé Lodash_.every
  • Sublinhado _.composeé Lodash_.flowRight
  • Sublinhado _.containsé Lodash_.includes
  • Sublinhado _.eachnão permite sair retornandofalse
  • Sublinhado _.findWhereé Lodash_.find
  • Sublinhado _.flattené profundo por padrão, enquanto Lodash é superficial
  • Sublinhado _.groupBysuporta uma iteratee que é passado os parâmetros (value, index, originalArray), enquanto em Lodash, o iteratee para _.groupBysó passou um único parâmetro: (value).
  • Sublinhado _.indexOfcom o terceiro parâmetro undefinedé Lodash_.indexOf
  • Sublinhado _.indexOfcom o terceiro parâmetro trueé Lodash_.sortedIndexOf
  • Sublinhado _.indexByé Lodash_.keyBy
  • Sublinhado _.invokeé Lodash_.invokeMap
  • Sublinhado _.mapObjecté Lodash_.mapValues
  • Sublinhado _.maxcombina Lodash _.max&_.maxBy
  • Sublinhado _.mincombina Lodash _.min&_.minBy
  • Sublinhado _.samplecombina Lodash _.sample&_.sampleSize
  • O sublinhado _.objectcombina Lodash _.fromPairse_.zipObject
  • Sublinhado _.omitpor um predicado é Lodash_.omitBy
  • Sublinhado _.pairsé Lodash_.toPairs
  • Sublinhado _.pickpor um predicado é Lodash_.pickBy
  • Sublinhado _.plucké Lodash_.map
  • Sublinhado _.sortedIndexcombina Lodash _.sortedIndex&_.sortedIndexOf
  • Sublinhado _.uniqpor um iterateeé Lodash_.uniqBy
  • Sublinhado _.whereé Lodash_.filter
  • O sublinhado _.isFinitenão se alinha com Number.isFinite
    (por exemplo, _.isFinite('1')retornos trueno sublinhado, mas falseno Lodash)
  • Sublinhado _.matchestaquigrafia não suporta comparações profundas
    (por exemplo _.filter(objects, { 'a': { 'b': 'c' } }))
  • Sublinhado ≥ 1,7 e a _.templatesintaxe Lodash é
    _.template(string, option)(data)
  • _.memoizeCaches Lodash são Mapcomo objetos
  • O Lodash não suporta um contextargumento para muitos métodos a favor de_.bind
  • Lodash suporta encadeamento implícito , encadeamento lento e fusão de atalhos
  • Lodash dividir sua sobrecarregado _.head, _.last, _.rest, e _.initialpara fora em
    _.take, _.takeRight, _.drop, & _.dropRight
    (ou seja, _.head(array, 2)em sublinhado é _.take(array, 2)em Lodash)
Iest
fonte
1
Eu já me deparei com esses problemas ao migrar e estou mantendo uma documentação cruzada (WIP) entre uma e a outra. Espero que seja útil para outras pessoas também!
luxon
60

Além da resposta de John, e lendo o lodash (que até então eu considerava um "eu-demais" para sublinhar), e vendo os testes de desempenho, lendo o código-fonte e as postagens do blog , os poucos pontos que fazem o lodash muito superiores ao sublinhado são:

  1. Não se trata da velocidade, mas da consistência da velocidade (?)

    Se você olhar para o código-fonte do sublinhado, verá nas primeiras linhas que o sublinhado recai nas implementações nativas de muitas funções. Embora em um mundo ideal, essa teria sido uma abordagem melhor, se você observar alguns dos links de desempenho apresentados nesses slides , não é difícil concluir que a qualidade dessas 'implementações nativas' varia muito no navegador. para o navegador. O Firefox é extremamente rápido em algumas das funções e, em alguns, o Chrome domina. (Eu imagino que haveria alguns cenários em que o IE também dominaria). Acredito que é melhor preferir um código cujo desempenho seja mais consistente nos navegadores.

    Leia a postagem do blog anteriormente e, em vez de acreditar nela, julgue por si mesmo executando os parâmetros de referência . Estou chocado agora, vendo um lodash executando 100-150% mais rápido que o sublinhado, mesmo em funções nativas simples , como no Chrome!Array.every

  2. Os extras no lodash também são bastante úteis.

  3. Quanto ao comentário altamente votado de Xananax, sugerindo uma contribuição para o código de sublinhado: é sempre melhor ter uma boa competição, além de manter a inovação ativa, mas também leva você a manter-se (ou a sua biblioteca) em boa forma.

Aqui está uma lista de diferenças entre o lodash e o underscore-build é um substituto para seus projetos de sublinhado.

kumarharsh
fonte
6
Nesse caso, a "consistência da velocidade" é um valor? Digamos, eu tenho um método que tem uma velocidade de 100% no FF e no IE e uma implementação nativa teria uma velocidade de 80% no IE e 120% no FF (ou o contrário). Então eu diria que seria bom usar a implementação nativa no FF e a própria implementação no IE. Não consigo imaginar nenhum caso, onde eu diria: Vamos desacelerar o FF apenas pelo motivo de ter a mesma velocidade no IE. O tamanho do código e a capacidade de manutenção ou uma desaceleração média em todos os navegadores seriam argumentos, mas consistência de velocidade?
stofl
2
Eu quis dizer, "consistentemente mais rápida velocidade"
kumarharsh
1
E a diferença de tamanho? Digamos que você crie uma compilação personalizada com lodash que tenha exatamente a mesma funcionalidade que o sublinhado? Existe uma grande diferença entre eles? Eu acho que a reimplementação adiciona peso ao site.
precisa saber é o seguinte
5
Estou inclinado a usar a implementação nativa do navegador simplesmente porque, na maioria dos casos, ele tem desempenho aceitável e pode melhorar as atualizações do navegador sem se preocupar em manter a biblioteca atualizada.
orad 21/07/14
3
@KumarHarsh Talvez eu não tenha expressado bem. Eu quis dizer que estou inclinado a usar uma biblioteca que internamente usa funções nativas, se disponível, em vez de sempre preferir sua própria implementação.
orad 3/12/14
42

Estamos em 2014 e dois anos tarde demais. Ainda acho que meu argumento é válido:

IMHO esta discussão ficou fora de proporção um pouco. Citando a postagem do blog acima mencionada :

A maioria das bibliotecas de utilitários JavaScript, como Underscore, Valentine e wu, conta com a "abordagem dual nativa em primeiro lugar". Essa abordagem prefere implementações nativas, voltando ao JavaScript básico somente se o equivalente nativo não for suportado. Mas o jsPerf revelou uma tendência interessante: a maneira mais eficiente de iterar sobre uma matriz ou coleção semelhante a uma matriz é evitar completamente as implementações nativas, optando por loops simples.

Como se "loops simples" e "Javascript vanilla" fossem mais nativos que as implementações de métodos Array ou Object. Eita ...

Certamente seria bom ter uma única fonte de verdade, mas não existe. Mesmo que você tenha dito o contrário, não há Deus Vanilla, minha querida. Eu sinto Muito. A única suposição que realmente vale é que todos nós estamos escrevendo código Javascript que visa ter um bom desempenho em todos os principais navegadores, sabendo que todos eles têm implementações diferentes das mesmas coisas. É uma merda lidar com isso, para dizer o mínimo. Mas essa é a premissa, goste ou não.

Talvez vocês estejam trabalhando em projetos de grande escala que precisam de desempenho twitterish, para que você realmente veja a diferença entre 850.000 (sublinhado) vs. 2.500.000 (lodash) iterações em uma lista por segundo agora!

Eu, pelo menos não sou. Quero dizer, trabalhei em projetos nos quais tinha que resolver problemas de desempenho, mas eles nunca foram resolvidos ou causados ​​por Underscore nem Lo-Dash. E, a menos que eu compreenda as diferenças reais de implementação e desempenho (estamos falando de C ++ agora), digamos um loop sobre um iterável (objeto ou matriz, esparso ou não!), Prefiro não me incomodar com nenhum reivindicações com base nos resultados de uma plataforma de benchmark que já é opinativa .

Ele precisa apenas de uma única atualização, digamos que o Rhino ative suas implementações do método Array de uma maneira que nem um único "método medieval de loop tenha um desempenho melhor e para sempre e outros" sacerdotes possam argumentar sobre o simples fato de que todos Os métodos de matriz repentina na FF são muito mais rápidos do que o seu cérebro opinativo. Cara, você simplesmente não pode enganar seu ambiente de execução enganando seu ambiente de execução! Pense nisso ao promover ...

seu cinto de utilidades

... próxima vez.

Portanto, para mantê-lo relevante:

  • Use Sublinhado se preferir, sem sacrificar o ish nativo.
  • Use o Lo-Dash se você gosta de conveniência e gosta do catálogo de recursos estendido (cópia detalhada etc.) e se precisa desesperadamente de desempenho instantâneo e, o mais importante, não se importa em optar por uma alternativa assim que a API nativa ofuscar soluções alternativas opinativas. O que acontecerá em breve. Período.
  • Existe até uma terceira solução. FAÇA VOCÊ MESMO! Conheça seus ambientes. Saiba sobre inconsistências. Leia o código deles (de John-David e Jeremy ). Não use isso ou aquilo sem poder explicar por que uma camada de consistência / compatibilidade é realmente necessária e aprimorar seu fluxo de trabalho ou melhorar o desempenho do seu aplicativo. É muito provável que seus requisitos sejam satisfeitos com um polyfill simples que você possa perfeitamente escrever. Ambas as bibliotecas são simplesmente baunilha com um pouco de açúcar. Os dois brigam por quem está servindo a torta mais doce . Mas acredite, no final, ambos estão apenas cozinhando com água. Não existe Deus da baunilha, então não pode haver Papa da baunilha, certo?

Escolha a abordagem que melhor atenda às suas necessidades. Como sempre. Eu preferiria fallbacks em implementações reais do que truques opinativos de tempo de execução a qualquer momento, mas mesmo isso parece ser uma questão de gosto hoje em dia. Atenha-se a recursos de qualidade como http://developer.mozilla.com e http://caniuse.com e você ficará bem.

Lukas Bünger
fonte
Obrigado por postar Lukas. Os internos podem ser otimizados ainda mais? Concluí que eles têm restrições impostas pelos padrões que os impedem de ter otimizações comparáveis ​​às bibliotecas, mas não conheço os detalhes de antemão ou se isso foi ou continua sendo verdade.
Brian M. caça
por exemplo "Ao otimizar para o caso de uso de 99%, os métodos fast.js podem ser até 5x mais rápidos que seus equivalentes nativos". - github.com/codemix/fast.js
Brian M. Hunt
1
Oi Brian, desculpe se isso foi enganoso, não quis dizer que essas bibliotecas não são muito mais rápidas que seus equivalentes nativos. Se você está precisando desesperadamente de desempenho no momento , provavelmente está melhor com um kit de ferramentas como LoDash ou fast.js, pois eles fornecem implementações mais rápidas de métodos padrão. Mas se você optar por usar uma biblioteca que não recorra a métodos nativos, poderá perder quaisquer otimizações futuras de desempenho nos built-ins. Os navegadores evoluirão eventualmente.
Lukas Bünger
4
Os "fabricantes" de navegadores têm dificuldade em manter os padrões de navegadores compatíveis, com muito menos desempenho. A maioria dos ganhos de desempenho nas implementações nativas é resultado de um hardware mais rápido. As "implementações nativas acompanharão" a desculpa existe há anos. Anos = eternidade na internet. Se as implementações nativas forem atualizadas, as bibliotecas serão atualizadas para usá-las. Essa é a coisa legal do código aberto. Se um desenvolvedor de aplicativos não atualizar para a biblioteca mais recente, o aplicativo não diminuirá repentinamente, apenas não acelerará.
Andrew Steitz
2
... mas se você perguntasse sobre Array.fromeles, provavelmente nem saberiam o que deveria fazer. O pessoal da JS "cinto de utilidades" parece estar tão preocupado com a promoção de soluções alternativas tão geniais que elas tendem a esquecer que, ao fazer isso, estão realmente diluindo o processo de padronização. Nenhuma necessidade de recursos leva a nenhuma pressão sobre os "fabricantes" do navegador. Curiosidade: dois dos quatro principais navegadores são baseados em projetos de código aberto ( 1 , 2 ).
Lukas Bünger
20

Estou de acordo com a maioria das coisas mencionadas aqui, mas só quero apontar um argumento a favor do underscore.js: o tamanho da biblioteca.

Especialmente no caso de você estar desenvolvendo um aplicativo ou site que pretende ser usado principalmente em dispositivos móveis, o tamanho do pacote resultante e o efeito no tempo de inicialização ou download podem ter um papel importante.

Para comparação, esses tamanhos são aqueles que notei com o source-map-explorer após executar o serviço iônico:

lodash: 523kB
underscore.js: 51.6kb

editado em fevereiro de 2020 :

pode-se usar o BundlePhobia para verificar o tamanho atual do Lo-Dash e Underscore

David Dal Busco
fonte
1
Obrigado Peter, este é um ponto interessante a ser observado aqui. Há mais discussões em outros lugares, incluindo: gist.github.com/alekseykulikov/5f4a6ca69e7b4ebed726 . (Essa resposta pode ser melhorada vinculando algumas das outras discussões e citando os bits relevantes) A ​​diferença de tamanho pode ser reduzida escolhendo subseções de lodash, mais lodash de agitação de árvores. 🕷
Brian M. Caça
Thx @ BrianM.Hunt pela sua resposta, não sabia que é possível incluir subseções de lodash, vamos dar uma olhada. Recentemente, com iônica nativo, Ionic tomou um tal caminho também para os seus libs nativas, bom notar que mais de um mais estão preocupados com o tamanho aplicativo
David Dal Busco
1
Gostaria de saber onde você conseguiu os 523kB? O lodash.com diz que é apenas 24kB compactado. o download é de apenas 74kB
Martian2049
1
meu post foi feito em abril de 2017. Como eu disse no meu comentário,source-map-explorer after running ionic serve
David Dal Busco
5
Em março de 2018 - lodash.min.js é de 72,5 kB e underscore-min.js é de 16,4 kB
Combine
10

Não tenho certeza se é isso que OP significava, mas me deparei com essa pergunta porque estava procurando uma lista de problemas que devo ter em mente ao migrar de sublinhado para lodash.

Eu realmente aprecio se alguém postou um artigo com uma lista completa dessas diferenças. Deixe-me começar com as coisas que aprendi da maneira mais difícil (ou seja, coisas que fizeram meu código explodir na produção: /):

  • _.flattenO sublinhado é profundo por padrão e você deve passar true como segundo argumento para torná-lo superficial. No lodash, é raso por padrão e passa true, pois o segundo argumento o tornará profundo! :)
  • _.lastem sublinhado aceita um segundo argumento que informa quantos elementos você deseja. Em lodashnão existe essa opção. Você pode emular isso com.slice
  • _.first (mesmo problema)
  • _.templateO sublinhado pode ser usado de várias maneiras, uma das quais é fornecer a sequência e os dados do modelo e HTMLvoltar (ou pelo menos foi assim que funcionou há algum tempo). Ao lodashreceber uma função que você deve alimentar com os dados.
  • _(something).map(foo)funciona em sublinhado, mas em lodash eu tive que reescrevê-lo para _.map(something,foo). Talvez isso fosse apenas uma TypeScriptquestão
qbolec
fonte
4
No lodash, o encadeamento passa por um iterador lento e requer um endpoint como _(something).map(foo).value().
Brian M. Caça
Isso tudo pode bater em você se você usar Coleção Backbone que proxies chamadas para essas bibliotecas - por exemplo collection.first (5) não vai lhe dar os primeiros 5 elementos, mas sim o primeiro :)
qbolec
8

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

Último artigo comparando os dois de Ben McCormick:

  1. A API do Lo-Dash é um superconjunto do Underscore.

  2. Sob o capô [Lo-Dash] foi completamente reescrito.

  3. Lo-Dash definitivamente não é mais lento que o Underscore.

  4. O que Lo-Dash adicionou?

    • Melhorias na usabilidade
    • Funcionalidade extra
    • Ganhos de desempenho
    • Sintaxe abreviada para encadeamento
    • Construções personalizadas para usar apenas o que você precisa
    • Versão semântica e 100% de cobertura de código
pilau
fonte
6

Acabei de encontrar uma diferença que acabou sendo importante para mim. A versão não-sublinhado compatível do lodash de _.extend()que não copiar propriedades ou métodos de classe definida de nível.

Eu criei um teste Jasmine no CoffeeScript que demonstra isso:

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

Felizmente, lodash.underscore.jspreserva o comportamento do Underscore de copiar tudo, o que para a minha situação era o comportamento desejado.

Craig Walker
fonte
4

O lodash possui um valor _.mapValues()idêntico ao do underescore _.mapObject().

cavaleiro
fonte
0

Na maior parte, o sublinhado é um subconjunto de lodash. Às vezes, como o sublinhado atualmente terá pequenas funções legais que o lodash não possui como o mapObject. Este me poupou muito tempo no desenvolvimento do meu projeto.

rashadb
fonte
no momento, temos _.mapValues
crapthings
@crapthings - no momento deste post, eu conhecia mayValues ​​e mapKeys, mas eles não são iguais a mapObject. Talvez haja casos para aplicar um sobre o outro, mas mapObject é uma função própria.
rashadb
0

Eles são bem parecidos, com Lodash assumindo o controle ...

Ambos são uma biblioteca de utilitários que leva o mundo da utilidade em JavaScript ...

Parece que o Lodash está sendo atualizado com mais regularidade agora, portanto, mais usado nos projetos mais recentes ...

Também o Lodash parece ser mais leve por alguns KBs ...

Ambos têm uma boa API e doc, mas acho que a Lodash é melhor ...

Aqui está uma captura de tela para cada um dos documentos para obter o primeiro valor de uma matriz ...

sublinhado:

sublinhado

lodash: lodash

Como as coisas podem ser atualizadas de tempos em tempos, basta verificar o site também ...

lodash

sublinhado

Alireza
fonte