lodash和下划线之间的区别[关闭]


1602

为什么有人会比其他人更喜欢lodash.jsunderscore.js实用程序库?

Lodash似乎是下划线的替代品,下划线的使用时间更长。

我认为两者都很出色,但是我对它们的工作方式还不够了解,无法进行有根据的比较,并且我想更多地了解差异。


2
您可能想看一下一些有关lodash 的截屏视频,这些视频在其github页面上链接到。就我个人而言,我一直在使用underscore.js,但更多的是因为这是我从这里开始的,而且正如您所说的,它已经存在了更长的时间。
2012年

26
lodashunderscore正在合并线程现在
zangw

Answers:


2022

我创建Lo-Dash的目的是为数组,字符串,对象和arguments对象1提供更一致的跨环境迭代支持。此后,它已成为Underscore的超集,提供更一致的API行为,更多功能(如AMD支持,深度克隆和深度合并),更全面的文档和单元测试(在Node,Ringo,Rhino,Narwhal,PhantomJS中运行的测试)和浏览器),可为大型数组/对象迭代提供更好的整体性能和优化,并通过自定义版本提供更大的灵活性和模板预编译实用程序。

由于Lo-Dash的更新频率比Underscore更新的频率高,因此提供了一个内部lodash underscore版本了以确保与Underscore的最新稳定版本兼容。

有一次我什至获得了推送访问权限 Underscore的,部分原因是Lo-Dash负责提出30多个问题。Underscore v1.4.x +中的着陆错误修复,新功能和性能提升。

另外,至少有3个Backbone样板默认包含Lo-Dash,并且Back-Bone的官方文档中现在提到了Lo-Dash 。

查看Kit Cambridge的帖子,向Lo-Dash说“你好”,以深入了解Lo-Dash和Underscore之间的区别。

脚注:

  1. 下划线对数组,字符串,对象和arguments对象的支持不一致。在较新的浏览器中,Underscore方法将忽略数组中的孔,“ Objects”方法将迭代arguments对象,将字符串视为类似于数组的方法,并且方法将正确地迭代函数(忽略其“ prototype”属性)和对象(迭代阴影的属性,例如“ toString”和“ valueOf”),而在较旧的浏览器中则不会。此外,Underscore方法(如_.clone保留数组中的孔),而其他方法_.flatten则不保留。

174
@Brian-在开发Lo-Dash时,我继续问一个问题:“在Lo-Dash中,与Underscore相比,有人会指出什么?” 然后解决它们。这就是为什么我要加强文档,添加自定义版本以及使源代码更具可读性的原因。
John-David Dalton

10
我很想发布一些基准,但这可能变得乏味。我只想说,每一个基准我已经运行已经证明罗短跑要快(MUCH比下划线在许多情况下更快)。
Wil Moore III

186
我喜欢lo-dash并且正在使用它,所以请不要以为我在抨击,但是为什么不贡献下划线而不是创建一个新的库呢?
Xananax

133
@Xananax-检查评论线程:github.com/jashkenas/underscore/commit / ...-这可以回答这个问题。
Rob Grant

41
是否有任何努力将lodash合并为下划线?
2014年

186

Lo-Dash受到下划线的启发,但如今已成为卓越的解决方案。您可以进行自定义构建,具有更高的性能,支持AMD并具有出色的额外功能。在jsperf上查看此Lo-Dash vs Underscore 基准测试。.. 关于lo-dash的真棒帖子

使用集合时,最有用的功能之一是速记语法:

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

(摘自lodash docs


1
Kit Cambridge博客的链接非常有用。
Brian M. Hunt

我认为这是错误的(摘录示例)。从上一次更新1.8.3开始,您可以使用与lodash相同的方式使用pluck。无论如何,对于以前的版本,我认为下划线不会公开与地图相同的函数(您的下划线示例似乎是地图函数)
alexserver

7
filter在下划线功能从2012年github.com/jashkenas/underscore/issues/648(其名称where
穆罕默德Hewedy

Lo-Dash vs
Underscore

86

如果像我一样,您期望下划线和lodash之间的用法差异列表,那么有一个从下划线迁移到lodash的指南

这是后代的当前状态:

  • 下划线_.any是Lodash_.some
  • 下划线_.all是Lodash_.every
  • 下划线_.compose是Lodash_.flowRight
  • 下划线_.contains是Lodash_.includes
  • 下划线_.each不允许通过返回退出false
  • 下划线_.findWhere是Lodash_.find
  • _.flatten默认情况下,下划线为深,而Lodash为浅
  • 下划线_.groupBy支持传递的参数的iteratee (value, index, originalArray),而在Lodash,对于iteratee _.groupBy仅通过一个参数:(value)
  • _.indexOf带第三个参数的下划线undefined是Lodash_.indexOf
  • _.indexOf带第三个参数的下划线true是Lodash_.sortedIndexOf
  • 下划线_.indexBy是Lodash_.keyBy
  • 下划线_.invoke是Lodash_.invokeMap
  • 下划线_.mapObject是Lodash_.mapValues
  • 下划线_.max结合Lodash _.max_.maxBy
  • 下划线_.min结合Lodash _.min_.minBy
  • 下划线_.sample结合Lodash _.sample_.sampleSize
  • 下划线_.object将Lodash _.fromPairs_.zipObject
  • _.omit谓词下划线是Lodash_.omitBy
  • 下划线_.pairs是Lodash_.toPairs
  • _.pick谓词下划线是Lodash_.pickBy
  • 下划线_.pluck是Lodash_.map
  • 下划线_.sortedIndex结合Lodash _.sortedIndex_.sortedIndexOf
  • 下划线_.uniqiteratee是Lodash_.uniqBy
  • 下划线_.where是Lodash_.filter
  • 下划线_.isFinite不符合Number.isFinite
    (例如,下划线_.isFinite('1')返回true,但false中的在Lodash中的值)
  • 下划线的_.matches简写不支持深度比较
    (例如_.filter(objects, { 'a': { 'b': 'c' } })
  • 下划线≥1.7&Lodash _.template语法为
    _.template(string, option)(data)
  • Lodash _.memoize缓存是Map就像对象
  • Lodash不支持context许多方法的参数来支持_.bind
  • Lodash支持隐式链接延迟链接和快捷方式融合
  • Lodash拆分它的过载_.head_.last_.rest,和_.initial伸到
    _.take_.takeRight_.drop,和_.dropRight
    (即_.head(array, 2)在下划线是_.take(array, 2)在Lodash)

1
在迁移时,我自己遇到了这些问题,并且我维护着相互之间的(WIP)交叉文档。希望它也对其他人有帮助!
卢森堡

60

除了John的回答,并阅读lodash(我迄今认为下划线是“我也很想强调”),并查看性能测试,阅读源代码和博客文章,这些使lodash的几点这些要比下划线要好得多:

  1. 这不关乎速度,而是关乎速度的一致性(?)

    如果查看下划线的源代码,您会在前几行中看到下划线是许多功能的本机实现的基础。尽管在理想的情况下,这本来是一种更好的方法,但是如果您看一下这些幻灯片中提供的一些性能链接,则不难得出这样的结论,即这些“本机实现”的质量在很多浏览器中都不同,浏览器。Firefox在某些功能上非常快速,在某些Chrome中占主导地位。(我想在某些情况下IE也将占主导地位)。我认为最好是使用跨浏览器性能更一致的代码。

    一定要早点阅读该博客文章,而不是为了它而相信它,而是通过运行基准来自己判断。我现在被惊呆了,看到即使在简单的原生功能(例如Array.everyChrome)中,lodash的执行速度也比下划线快100-150%!

  2. 临时演员lodash也非常有用。

  3. 至于Xananax极力支持的评论,它暗示了对下划线代码的贡献:拥有GOOD竞争总是更好,这不仅可以保持创新,还可以驱使您(或您的图书馆)保持良好状态。

这是lodash之间差异列表,并且underscore-build是下划线项目的直接替代品。


6
在哪种情况下“速度一致性”是一个值?假设,我有一种方法,在FF和IE中速度为100%,而本机实现在IE和FF中速度为80%(或相反)。然后,我想说最好在FF中使用本机实现,而在IE中使用自己的实现。我无法想像任何情况,我会说:让FF变慢只是因为它具有与IE中相同的速度。代码大小和可维护性,或者所有浏览器的平均速度下降都是参数,但是速度是否一致?
stofl 2013年

2
我的意思是“始终保持更快的速度”
kumarharsh

1
大小差异如何?假设您使用lodash创建具有与下划线完全相同功能的自定义版本?它们之间有很大的区别吗?我猜想重新实现会增加网站的分量。
F Lekschas

5
我倾向于回退到浏览器的本机实现,因为在大多数情况下,它具有可接受的性能,并且可以随着浏览器更新而改进,而不必担心使库保持最新。
orad 2014年

3
@KumarHarsh也许我说得不好。我的意思是,我倾向于使用一个库,该库在内部使用本机函数(如果可用),而不是始终偏向于自己的实现。
orad 2014年

42

这是2014年,并且为时已晚。我仍然认为我的观点是正确的:

恕我直言,这一讨论不合比例。引用上述博客文章

大多数JavaScript实用程序库(例如Underscore,Valentine和wu)都依赖于“本机优先双重方法”。这种方法更喜欢本机实现,只有在不支持本机等效功能时,才使用原始JavaScript。但是jsPerf揭示了一个有趣的趋势:遍历数组或类似数组的集合的最有效方法是完全避免本机实现,而选择简单的循环。

好像“简单循环”和“原始Javascript”比Array或Object方法实现更原生。哎呀...

有一个单一的事实来源当然会很好,但事实并非如此。亲爱的,即使有人告诉您,也没有香草神。对不起。真正成立的唯一假设是,我们都在编写旨在在所有主要浏览器中都表现良好的Javascript代码,因为他们知道所有这些浏览器都有相同的事物的不同实现。温和地说,这是一个应付的ch子。但这是前提,无论您是否喜欢。

也许你们所有人都在从事需要微调性能的大型项目,所以您现在可以在每秒列表上真正看到850,000(下划线)与2,500,000(lodash)迭代之间的差异!

我不是一个。我的意思是,我在必须解决性能问题的项目中工作,但是这些问题从未解决过,也不是由Underscore或Lo-Dash引起的。而且,除非我掌握了实现和性能的真正差异(我们现在正在谈论C ++),让我们说一个遍历可迭代对象(对象或数组,稀疏与否!)的循环,否则我不会为任何问题所困扰根据已经被接受的基准平台的结果进行声明

它只需要更新一次,比如说Rhino,就可以以一种方式让Array方法的实现着火,这种方式不会让任何一个“中世纪循环方法表现得更好,永远如此,而牧师不会”就这样一个简单的事实争论自己: FF中的突然排列方法比他/她自以为是的头脑快得多。伙计,您只是不能通过欺骗运行时环境来欺骗运行时环境!推广时考虑一下...

你的腰带

... 下次。

因此,保持相关性:

  • 如果您在不牺牲本机语言的情况下方便使用,请使用Underscore。
  • 如果您方便使用并且喜欢它的扩展功能目录(深拷贝等),并且急需即时性能,并且最重要的是,不介意在本机API消失后立即解决,请使用Lo-Dash。固执己见的工作环境。这将很快发生。期。
  • 甚至还有第三种解决方案。DIY!了解您的环境。了解不一致之处。阅读他们的(John-DavidJeremy的)代码。在无法解释为什么确实需要一致性/兼容性层并增强您的工作流程或提高应用程序性能的情况下,请不要使用它。一个非常有能力自己编写自己的简单polyfill就能满足您的要求。这两个库都是纯香草味的,并带有一点点糖。他们俩都在争夺谁在为最甜蜜的派服务。但请相信我,最终两者都只用水煮饭。没有香草神,所以就没有香草教皇,对吗?

选择最适合您需求的方法。照常。我宁愿随时随地对实际实现进行回退,也不要选择任何固执己见的运行时作弊手段,但如今看来,这仍然是个问题。坚持使用http://developer.mozilla.comhttp://caniuse.com之类的优质资源,一切都会好起来的。


感谢您发布Lukas。可以进一步优化内置功能吗?我收集到它们受到标准的约束,使它们无法进行与库可比的优化,但是我不了解细节,也不清楚这是否是正确的。
Brian M. Hunt 2014年

例如:“通过针对99%的用例进行优化,fast.js方法可以比其本机等效方法快5倍。” – github.com/codemix/fast.js
Brian M. Hunt

1
嗨,布莱恩,很抱歉,如果这令人误解,我并不是要说这些库的运行速度并不比其本地等效库快多少。如果您在性能迫切需要是正确的,现在,你为他们提供更快的标准方法的实现可能会更好过与像LoDash或fast.js的工具包。但是,如果您选择使用不依赖本机方法的库,则可能会错过内置组件将来的任何性能优化。浏览器将最终发展。
LukasBünger2014年

4
浏览器“制造商”很难保证其浏览器符合标准,而性能却低得多。本机实现中的大多数性能提升是硬件速度更快的结果。“本机实现将迎头赶上”的借口已经存在多年了。年=互联网上的永恒。如果本机实现赶上来,则将更新库以使用它们。开源是一件很酷的事情。如果应用程序开发人员没有更新到最新的库,那么他们的应用程序不会突然变慢,只会加速。
Andrew Steitz 2014年

2
...但是如果您问他们有关Array.from他们的信息,他们甚至可能都不知道应该怎么做。JS“工具带”人们似乎过于关注推广自己的通用变通方法,以至于他们往往忘记这样做,实际上是在稀释标准化过程。不需要功能不会对浏览器“制造商”造成压力。有趣的事实:的4级主要的浏览器2是基于开源项目(12)。
LukasBünger2014年

20

我同意这里所说的大多数内容,但是我只想指出一个支持underscore.js的论点:库的大小。

特别是在您开发要主要在移动设备上使用的应用或网站的情况下,所得捆绑包的大小以及对启动或下载时间的影响可能会发挥重要作用。

为了进行比较,这些大小是运行离子服务后我在source-map-explorer中注意到的大小:

lodash: 523kB
underscore.js: 51.6kb

2020年2月编辑:

人们可以使用BundlePhobia检查的当前大小罗短跑下划线


1
谢谢彼得,在这里值得一提。其他地方还有更多讨论,包括:gist.github.com/alekseykulikov/5f4a6ca69e7b4ebed726。(可以通过链接其他一些讨论并引用相关的位来改善此答案)。可以通过选择lodash的各个部分以及摇树的lodash来减小大小上的差异。🕷
布赖恩M.亨特

谢谢@ BrianM.Hunt的回复,不知道有可能包含lodash的各个部分,请看一看。Ionic最近与ionic-native一起为自己的本地库走了一条路,值得一提的是,越来越多的人关注应用的大小
David Dal Busco

1
我不知道您从哪里得到523kB?lodash.com说它只有24kB压缩。下载的文件仅为74kB
Martian2049'3

1
我的帖子发表于2017年4月。就像我在评论中所说,source-map-explorer after running ionic serve
David Dal Busco

5
在2018年3月-lodash.min.js为72.5 kB,underscore-min.js为16,4 kB
结合

10

不知道这是否是OP的意思,但是我遇到了这个问题,因为我在搜索从下划线迁移到lodash时必须牢记的问题列表。

如果有人发布一篇包含此类差异的完整列表的文章,我将不胜感激。让我从我艰难学习的东西开始(即,使我的代码在生产中爆炸的东西:/):

  • _.flatten下划线默认是深的,您必须将true作为第二个参数传递以使其变浅。在lodash中,默认情况下它是浅的,而将true作为第二个参数传递将使其变深!:)
  • _.last下划线中的in接受第二个参数,该参数告诉您要多少个元素。在lodash没有这样的选项。您可以使用.slice
  • _.first (同一期)
  • _.template下划线中的可以有多种使用方式,其中一种是提供模板字符串和数据并HTML取回(或者至少是一段时间前的工作方式)。在lodash其中,您将收到一个函数,然后应将其提供给数据。
  • _(something).map(foo)在下划线下工作,但在lodash中我不得不将其重写为_.map(something,foo)。也许那只是一个TypeScript问题

4
在lodash中,链接通过一个懒惰的迭代器,并且需要和端点类似_(something).map(foo).value()
Brian M. Hunt

如果您使用代理到这些库的调用的Backbone Collection,这一切都会对您造成打击-例如,collection.first(5)不会给您前五个元素,而是第一个元素:)
qbolec

8

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

Ben McCormick的最新文章将两者进行了比较:

  1. Lo-Dash的API是Underscore的超集。

  2. 引擎盖下的[Lo-Dash]已被完全重写。

  3. Lo-Dash绝对不比Underscore慢。

  4. Lo-Dash添加了什么?

    • 可用性改进
    • 额外功能
    • 绩效提升
    • 链接的简写语法
    • 自定义构建仅使用您需要的内容
    • 语义版本控制和100%的代码覆盖率

6

我只是发现一个差异对我来说很重要。lodash的的非下划线兼容的版本_.extend()确实拷贝过来的类级定义的属性或方法。

我已经在CoffeeScript中创建了一个Jasmine测试,以证明这一点:

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

幸运的是,lodash.underscore.js保留了Underscore复制所有内容的行为,这对我来说是理想的行为。


4

lodash得到_.mapValues()的与下划线的相同_.mapObject()


0

大多数情况下,下划线是lodash的子集。有时,像现在的下划线一样,会有一些很棒的小功能,而lodash却不像mapObject。这为我节省了很多时间来开发我的项目。


当时,我们有_.mapValues
令人毛骨悚然

@crapthings-在撰写本文时,我知道mayValues和mapKeys,但它们与mapObject不同。也许在某些情况下可以套用一个对象,但mapObject是一个单独的函数。
rashadb

0

它们非常相似,Lodash接管了...

它们都是实用程序库,它们利用JavaScript的实用程序领域...

似乎洛达什现在正在定期更新,因此在最新项目中使用了更多...

还有罗达似乎是一对夫妇KB的打火机......

两者都有很好的API和文档,但我认为Lodash更好。

这是每个文档的屏幕快照,用于获取数组的第一个值...

下划线:

下划线

lodash: Lodash

由于情况可能会不时更新,因此也请检查其网站...

Lodash

下划线

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.