underscore.js - underscore - lodash validate
Las diferencias entre lodash y subrayado (11)
Acabo de encontrar una diferencia que terminó siendo importante para mí. La versión no subrayada del _.extend()
de _.extend()
no se copia sobre propiedades o métodos definidos a nivel de clase.
He creado una prueba de Jasmine en CoffeeScript que demuestra esto:
https://gist.github.com/softcraft-development/1c3964402b099893bd61
Afortunadamente, lodash.underscore.js
conserva el comportamiento de Underscore de copiar todo, que para mi situación era el comportamiento deseado.
¿Por qué alguien preferiría la biblioteca de utilidades lodash.js o underscore.js sobre la otra?
Lodash parece ser un sustituto directo del guión bajo, ya que este último ha existido por más tiempo.
Creo que ambos son brillantes, pero no sé lo suficiente sobre cómo funcionan para hacer una comparación educada, y me gustaría saber más sobre las diferencias.
Además de la respuesta de John, y leer sobre lodash (que hasta ahora había considerado como un "yo también" para subrayar), y ver las pruebas de rendimiento, leer el código fuente y las publicaciones del blog , los pocos puntos que hacen de lodash. mucho mejor para subrayar son estos:
No se trata de la velocidad, sino de la consistencia de la velocidad (?)
Si examina el código fuente del guión bajo, verá en las primeras líneas que subrayan el retroceso en las implementaciones nativas de muchas funciones. Aunque en un mundo ideal, este podría haber sido un mejor enfoque, si observa algunos de los enlaces que se muestran en estas diapositivas , no es difícil sacar la conclusión de que la calidad de esas ''implementaciones nativas'' varía mucho en el navegador. al navegador Firefox es muy rápido en algunas de las funciones, y en algunos domina Chrome. (Me imagino que habría algunos escenarios donde IE también dominaría). Creo que es mejor preferir un código cuyo rendimiento sea más consistente en todos los navegadores.
Lea la publicación del blog antes, y en lugar de creerlo por su bien, juzgue por sí mismo ejecutando los puntos de referencia . Estoy aturdido en este momento, al ver a un lodash realizando 100-150% más rápido que el subrayado en funciones incluso simples y nativas como
Array.every
. ¡Array.every
en Chrome!Los extras en lodash también son bastante útiles.
- En cuanto al comentario altamente promocionado de Xananax que sugiere una contribución al código de subrayado: siempre es mejor tener BUENA competencia, no solo mantiene la innovación, sino que también lo impulsa a mantenerse (oa su biblioteca) en buena forma.
Aquí hay una lista de diferencias entre lodash, y su subrayado-build es un reemplazo directo para sus proyectos de subrayado.
Creé Lo-Dash para proporcionar compatibilidad de iteración entre entornos, más consistente para matrices, cadenas, objetos y arguments
objetos 1 . Desde entonces se ha convertido en un superconjunto de Underscore, que proporciona un comportamiento de API más consistente, más lodash.js (como el soporte de AMD, clonación profunda y fusión profunda), documentation más completa y pruebas unitarias (pruebas que se ejecutan en Node, Ringo, Rhino, Narwhal, PhantomJS). y navegadores), mejor rendimiento general y optimizaciones para arrays grandes / iteración de objetos, y más flexibilidad con lodash.js y utilidades de lodash.js plantillas.
Debido a que Lo-Dash se actualiza con más frecuencia que Underscore, lodash.js una lodash underscore
para garantizar la compatibilidad con la última versión estable de Underscore.
En un momento dado, incluso me dieron acceso a Underscore, en parte porque Lo-Dash es responsable de plantear más de 30 problemas; correcciones de errores de aterrizaje, nuevas funciones y mejoras de rendimiento en Underscore v1.4.x +.
Además, hay al menos 3 repeticiones de Backbone que incluyen Lo-Dash por defecto y Lo-Dash ahora se menciona en la documentation oficial de Backbone.
Echa un vistazo a la publicación de Kit Cambridge, Dile "Hola" a Lo-Dash , para obtener un desglose más profundo sobre las diferencias entre Lo-Dash y el subrayado.
Notas al pie:
- El guión bajo tiene soporte incoherente para arrays, cadenas, objetos y objetos de
arguments
. En los navegadores más nuevos, los métodos de subrayado ignoran los orificios en las matrices , los métodos de "Objetos" repiten losarguments
, las cadenas se tratan como matrices y los métodos itera correctamente las funciones (ignorando su propiedad de "prototipo") y los objetos (iterar las propiedades sombreadas como "toString" y "valueOf"), mientras que en los navegadores más antiguos no lo harán. Además, los métodos de_.clone
como_.clone
conservan los agujeros en los arreglos, mientras que otros como_.flatten
no lo hacen.
En su mayor parte, el subrayado es subconjunto de lodash. A veces, como el subrayado actual tendrá pequeñas funciones geniales que lodash no tiene como mapObject. Este me ahorró mucho tiempo en el desarrollo de mi proyecto.
Esto es 2014 y un par de años demasiado tarde. Todavía creo que mi punto es válido:
En mi humilde opinión esta discusión se salió de la proporción un poco. Citando la entrada de blog antes mencionada:
La mayoría de las bibliotecas de utilidades de JavaScript, como Underscore, Valentine y wu, se basan en el "primer enfoque dual nativo". Este enfoque prefiere implementaciones nativas, recurriendo a JavaScript vainilla solo si el equivalente nativo no es compatible. Pero jsPerf reveló una tendencia interesante: la forma más eficiente de recorrer una matriz o una colección similar a una matriz es evitar las implementaciones nativas por completo, optando por bucles simples en su lugar.
Como si los "bucles simples" y el "Javascript de vainilla" fueran más nativos que las implementaciones de métodos de Array u Objeto. Dios ...
Ciertamente sería bueno tener una sola fuente de verdad, pero no la hay. Incluso si le han dicho lo contrario, no hay un Dios Vainilla, querida. Lo siento. El único supuesto que realmente se sostiene es que todos estamos escribiendo código Javascript que apunta a tener un buen desempeño en todos los navegadores principales, sabiendo que todos ellos tienen implementaciones diferentes de las mismas cosas. Es una perra para hacer frente, para decirlo suavemente. Pero esa es la premisa, te guste o no.
¡Quizás estén trabajando en proyectos a gran escala que necesitan un rendimiento de Twitter para que realmente vea la diferencia entre las iteraciones de 850,000 (subrayado) y las de 2,500,000 (lodash) en una lista por segundo en este momento!
Yo, por mi parte, no lo soy. Quiero decir, trabajé en proyectos en los que tuve que abordar problemas de rendimiento, pero nunca fueron resueltos ni causados por el guión bajo ni por Lo-Dash. Y a menos que consiga las diferencias reales en la implementación y el rendimiento (estamos hablando de C ++ en este momento) de digamos un bucle sobre un iterable (objeto o matriz, dispersos o no!), Prefiero que no me moleste con nada. Reclamaciones basadas en los resultados de una plataforma de referencia que ya está criticada .
Solo necesita una única actualización. Digamos que Rhino prende fuego a las implementaciones de su método Array de una manera que ni un solo "método de bucle medieval funciona mejor y para siempre", y el sacerdote puede argumentar a su manera sobre el simple hecho de que todos los métodos de una matriz repentina en FF son mucho más rápidos que los de su / su opinión. ¡Hombre, simplemente no puedes engañar a tu entorno de ejecución al engañar a tu entorno de ejecución! Piensa en eso cuando promocione ...
su cinturón utilitario
... la próxima vez.
Así que para mantenerlo relevante:
- Usa el subrayado si te gusta la conveniencia sin sacrificar el ish nativo.
- Use Lo-Dash si le gusta la comodidad y le gusta su catálogo de funciones extendido (copia profunda, etc.) y si necesita desesperadamente un rendimiento instantáneo y, lo que es más importante, no le importa conformarse con una alternativa tan pronto como la API nativa brille. Workaurounds opinados. Lo que va a pasar pronto. Período.
- Incluso hay una tercera solución. Bricolaje Conoce tus entornos. Saber sobre inconsistencias. Lea su código ( John-David ''s y Jeremy '' s). No use esto o aquello sin poder explicar por qué una capa de consistencia / compatibilidad es realmente necesaria y mejora su flujo de trabajo o mejora el rendimiento de su aplicación. Es muy probable que sus requisitos queden satisfechos con un simple relleno de polietileno que puede escribir usted mismo perfectamente. Ambas bibliotecas son simplemente de vainilla con un poco de azúcar. Ambos se pelean por quién está sirviendo la tarta más dulce . Pero créeme, al final ambos solo se cocinan con agua. No hay un Dios de vainilla, así que no puede haber un Papa de vainilla, ¿verdad?
Elija el enfoque que más se ajuste a sus necesidades. Como siempre. Preferiría reservas en implementaciones reales en lugar de trucos de runtime opinados en cualquier momento, pero incluso eso parece ser una cuestión de gustos en la actualidad. Cumpla con recursos de calidad como http://developer.mozilla.com y http://caniuse.com y estará bien.
Estoy de acuerdo con la mayoría de las cosas que se mencionan aquí, pero solo quiero señalar un argumento a favor de underscore.js: el tamaño de la biblioteca.
Especialmente en el caso de que esté desarrollando una aplicación o sitio web que tenga la intención de ser utilizado principalmente en dispositivos móviles, el tamaño del paquete resultante y el efecto en el tiempo de arranque o de descarga pueden tener un papel importante.
A modo de comparación, estos tamaños son los que noté con source-map-explorer después de ejecutar el servicio iónico:
lodash: 523kB
underscore.js: 51.6kb
Lo-Dash está inspirado en el subrayado, pero hoy en día es una solución superior. Puede hacer sus compilaciones personalizadas , tener un mayor rendimiento , ser compatible con AMD y tener excelentes funciones adicionales . Verifique estos puntos de referencia Lo-Dash vs Underscore en jsperf y ... esta increíble publicación sobre lo-dash :
Una de las características más útiles cuando trabajas con colecciones, es la sintaxis 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 }]
(tomado de documentos de lodash )
No estoy seguro de si eso es lo que quería decir OP, pero me topé con esta pregunta porque estaba buscando una lista de problemas que tengo que tener en cuenta al migrar del subrayado al lodash.
Realmente apreciaría si alguien publicara un artículo con una lista completa de tales diferencias. Permítanme comenzar con las cosas que aprendí de la manera más difícil (es decir, las cosas que hicieron que mi código explotara en la producción: /):
-
_.flatten
en el guión bajo es profundo por defecto y tienes que pasar verdadero como segundo argumento para hacerlo superficial. En lodash es superficial por defecto y pasa verdadero como segundo argumento lo hará profundo! :) -
_.last
in subrayado acepta un segundo argumento que indica cuántos elementos desea. Enlodash
no hay tal opción. Puedes emular esto con.slice
-
_.first
(mismo problema) -
_.template
en el guión bajo se puede usar de muchas maneras, una de las cuales es proporcionar la cadena y los datos de la plantilla y recuperarHTML
(o al menos así es como funcionó hace algún tiempo). Enlodash
usted recibe una función que luego debe alimentar con los datos. -
_(something).map(foo)
funciona en guión bajo, pero en lodash tuve que reescribirlo en_.map(something,foo)
. Tal vez eso fue sólo una edición deTypeScript
Si, como yo, esperabas una lista de las diferencias de uso entre el guión bajo y el dato, hay una guía para migrar del guión bajo .
Aquí está el estado actual de la posteridad:
- El
_.compose
bajo_.flowRight
es Lodash_.flowRight
- El
_.contains
es Lodash_.includes
- Subrayado
_.findWhere
esta Lodash_.find
_.invoke
es Lodash_.invokeMap
- Subrayado
_.mapObject
is Lodash_.mapValues
- Subrayado
_.pluck
es Lodash_.map
- Subrayado
_.where
esta Lodash_.filter
- Subrayado
_.any
es Lodash_.some
- Subrayado
_.all
es Lodash_.every
._.every
- Subrayado
_.each
no permite salir devolviendofalse
- El
_.flatten
es profundo por defecto mientras que Lodash es poco profundo_.isFinite
no se alinea conNumber.isFinite
(por ejemplo,_.isFinite(''1'')
devuelvetrue
en el guión bajo perofalse
en Lodash)- El
_.matches
taquigrafía no admite comparaciones profundas
(por ejemplo,_.filter(objects, { ''a'': { ''b'': ''c'' } })
)- Subrayado ≥ 1.7 y Lodash han cambiado su sintaxis
_.template
a
_.template(string, option)(data)
- Lodash
_.uniq
no acepta una funcióniteratee
como la de Underscore. Usa Lodash_.uniqBy
- Lodash
_.first
y._last
no aceptan un argumento como el de Underscore. Usarslice
- Lodash
_.memoize
caches sonMap
como objetos- Lodash admite el encadenamiento implícito , el encadenamiento perezoso y la fusión de accesos directos
- Lodash dividió su sobrecargado
_.head
,_.last
,_.rest
, y_.initial
en
_.take
,_.takeRight
,_.drop
, &_.dropRight
(es decir,_.head(array, 2)
en el_.take(array, 2)
es_.take(array, 2)
en Lodash)
http://benmccormick.org/2014/11/12/underscore-vs-lodash/
Último artículo comparando los dos por Ben McCormick:
La API de Lo-Dash es un superconjunto de Underscore.
Bajo el capó [Lo-Dash] ha sido completamente reescrito.
Lo-Dash definitivamente no es más lento que el guión bajo.
¿Qué ha añadido Lo-Dash?
- Mejoras de usabilidad
- Funcionalidad Extra
- Ganancias de rendimiento
- Sintaxis abreviadas para el encadenamiento.
- Diseños personalizados para usar solo lo que necesitas
- Versiones semánticas y cobertura de código al 100%.
lodash tiene _.mapValues()
que es idéntico a _.mapObject()
guiones _.mapObject()
.