1686

为什么有人更喜欢LodashUnderscore.js实用程序库而不是另一个?

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

我认为两者都很出色,但我对它们如何进行有根据的比较知之甚少,我想了解更多关于差异的信息。

4

12 回答 12

2117

arguments我创建 Lodash 是为了为数组、字符串、对象和对象1提供更一致的跨环境迭代支持。它已经成为 Underscore.js 的超集,提供更一致的 API 行为、更多功能(如 AMD 支持、深度克隆和深度合并)、更全面的文档和单元测试(在Node.jsRingoJSRhino中运行的测试) 、NarwhalPhantomJS和浏览器),更好的整体性能和大型数组/对象迭代的优化,以及自定义构建和模板预编译实用程序的更大灵活性。

由于 Lodash 比 Underscore.js 更新更频繁,因此提供lodash underscore了一个构建以确保与 Underscore.js 的最新稳定版本兼容。

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

此外,至少有三个Backbone.js样板默认包含 Lodash,并且 Lodash 现在在 Backbone.js 的官方文档中被提及。

查看 Kit Cambridge 的帖子,向 Lo-Dash 说“Hello”,以更深入地了解 Lodash 和 Underscore.js 之间的差异。

脚注:

  1. Underscore.js 对数组、字符串、对象和arguments对象的支持不一致。在较新的浏览器中,Underscore.js 方法忽略数组中的漏洞,“对象”方法迭代arguments对象,字符串被视为类似数组,方法正确地迭代函数(忽略它们的“原型”属性)和对象(迭代阴影属性,如“toString " 和 "valueOf"),而在旧版浏览器中则不会。此外,Underscore.js 方法,如_.clone,保留数组中的孔,而其他方法_.flatten则不保留。
于 2012-12-16T05:34:06.213 回答
197

Lodash 受到 Underscore.js 的启发,但现在它是一种出色的解决方案。您可以进行自定义构建,拥有更高的性能,支持 AMD 并拥有出色的额外功能。检查jsperf 上的 Lodash 与Underscore.js 基准测试,以及……这篇关于 Lodash 的精彩帖子

当您使用集合时,最有用的功能之一是简写语法:(
尽管 Underscore 现在也支持这种语法)

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

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

// Using Underscore.js
_.filter(characters, function(character) { return character.age === 36; } );

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

(取自Lodash 文档

于 2012-12-13T21:51:14.147 回答
104

如果您像我一样期待 Underscore.js 和 Lodash 之间的使用差异列表,那么这里有一个从 Underscore.js 迁移到 Lodash 的指南

以下是它的当前状态供后代使用:

  • 下划线_.any是 Lodash_.some
  • 下划线_.all是 Lodash_.every
  • 下划线_.compose是 Lodash_.flowRight
  • 下划线_.contains是 Lodash_.includes
  • 下划线_.each不允许通过返回退出false
  • 下划线_.findWhere是 Lodash_.find
  • 下划线_.flatten默认是深的,而 Lodash 是浅的
  • Underscore_.groupBy支持传递参数(value, index, originalArray)的迭代器,而在 Lodash 中,迭代器 for_.groupBy只传递一个参数:(value).
  • Underscore.js_.indexOf的第三个参数undefined是 Lodash_.indexOf
  • Underscore.js_.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
  • 下划线_.uniqiterateeLodash_.uniqBy
  • 下划线_.where是 Lodash_.filter
  • 下划线_.isFinite不符合Number.isFinite
    (例如在 Underscore.js 中_.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, & _.initialout 拆分为
    _.take, _.takeRight, _.drop, & _.dropRight
    (即在 Underscore.js_.head(array, 2)中是_.take(array, 2)在 Lodash 中)
于 2016-07-21T09:35:51.107 回答
60

除了John 的回答,阅读 Lodash(迄今为止我一直认为它是 Underscore.js 的“我也是”),以及查看性能测试、阅读源代码和博客文章之外,还有几点使 Lodash 优于 Underscore.js 的有以下几点:

  1. 这与速度无关,因为它与速度的一致性有关(?)

如果您查看 Underscore.js 的源代码,您会在前几行中看到 Underscore.js 依赖于许多函数的本机实现。尽管在理想情况下,这将是一种更好的方法,但如果您查看这些幻灯片中给出的一些性能链接,不难得出结论,这些“本机实现”的质量因浏览器而异——到浏览器。Firefox 在某些功能上非常快,而在某些 Chrome 中占主导地位。(我想在某些情况下 Internet Explorer 也会占主导地位)。我认为最好选择跨浏览器性能更一致的代码。

一定要早点阅读这篇博文,不要因为它而相信它,而是通过运行基准来自己判断。我现在惊呆了,看到 Lodash在 Chrome 等简单原生函数中的性能比 Underscore.js 快 100-150% Array.every

  1. Lodash中的附加功能也非常有用。
  2. 至于 Xananax 的高度评价建议对 Underscore.js 的代码做出贡献的评论:拥有良好的竞争总是更好,它不仅可以保持创新,还可以促使您保持自己(或您的库)处于良好状态。

这是Lodash 之间的差异列表,它的 Underscore.js 构建是您的 Underscore.js 项目的直接替代品。

于 2013-08-18T14:18:59.610 回答
42

在 2014 年,我仍然认为我的观点成立:

恕我直言,这个讨论被夸大了。引用上述博客文章

大多数 JavaScript 实用程序库,例如 Underscore、Valentine 和 wu,都依赖于“native-first dual approach”。这种方法更喜欢原生实现,只有在不支持原生等价物的情况下才回退到原生 JavaScript。但是 jsPerf 揭示了一个有趣的趋势:迭代数组或类似数组的集合的最有效方法是完全避免原生实现,而是选择简单的循环。

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

拥有单一的事实来源当然很好,但没有。即使你被告知不是这样,也没有香草之神,亲爱的。对不起。唯一真正成立的假设是,我们都在编写旨在在所有主流浏览器中表现良好的 JavaScript 代码,并且知道它们都有相同事物的不同实现。委婉地说,这是一个要应付的婊子。但这是前提,不管你喜不喜欢。

也许你们所有人都在从事需要 twitter 性能的大型项目,以便您现在真正看到每秒列表中 850,000 (Underscore.js) 与 2,500,000 (Lodash) 迭代之间的区别!

我不是。我的意思是,我从事的项目必须解决性能问题,但这些问题从未得到解决,也不是由 Underscore.js 和 Lodash 引起的。除非我掌握了实现和性能(我们现在正在谈论 C++)的真正差异,比如说,一个可迭代的循环(对象或数组,稀疏与否!),我宁愿不被打扰任何声明都基于已经自以为是的基准平台的结果。

它只需要一个单一的更新,比方说,Rhino以一种方式将它的 Array 方法实现点燃,没有一个单一的“中世纪循环方法性能更好,永远和诸如此类”的牧师可以围绕一个简单的事实争论他/她的方式突然之间,Firefox 中的数组方法比他/她自以为是的笨蛋要快得多。伙计,你不能通过欺骗你的运行时环境来欺骗你的运行时环境!宣传的时候想想...

你的实用腰带

... 下次。

所以要保持相关性:

  • 如果您在不牺牲原生风格的情况下获得便利,请使用 Underscore.js。
  • 如果您喜欢 Lodash 的便利性并喜欢它的扩展功能目录(深拷贝等),并且如果您迫切需要即时性能并且最重要的是不介意在原生 API 胜过固执己见时立即选择替代方案变通方法。这很快就会发生。时期。
  • 甚至还有第三种解决方案。DIY!了解您的环境。了解不一致之处。阅读他们(John-DavidJeremy的)代码。在无法解释为什么真正需要一致性/兼容性层并增强您的工作流程或提高应用程序性能的情况下,不要使用这个或那个。很可能您的要求可以满足您完全能够自己编写的简单polyfill 。这两个库都只是加了一点糖的普通香草。他们俩只是为了谁提供最甜的馅饼而争吵。但请相信我,最终两者都只是用水做饭。没有香草神,所以不可能没有香草教皇,对吧?

选择最适合您需求的任何方法。照常。我更喜欢在任何时候对实际实现进行回退,而不是自以为是的运行时作弊,但即使这在当今似乎也是一个品味问题。坚持使用像http://developer.mozilla.comhttp://caniuse.com这样的优质资源,你会没事的。

于 2014-09-11T21:27:19.333 回答
25

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

特别是如果您正在开发一个打算主要在移动设备上使用的应用程序或网站,则生成的捆绑包的大小以及对启动或下载时间的影响可能具有重要作用。

作为比较,这些尺寸是我在运行Ionic serve 后使用 source-map-explorer 注意到的尺寸:

Lodash: 523 kB
Underscore.js: 51.6 kB

可以使用BundlePhobia检查LodashUnderscore.js的当前大小。

于 2017-04-26T14:20:40.207 回答
11

我不确定这是否是 OP 的意思,但我遇到了这个问题,因为我正在搜索从 Underscore.js 迁移到 Lodash 时必须牢记的问题列表。

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

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

Ben McCormick 的Underscore vs Lo-Dash是比较两者的最新文章:

  1. Lodash 的 API 是 Underscore.js 的超集。
  1. 在引擎盖下,Lodash 已被完全重写。
  1. Lodash 绝对不比 Underscore.js 慢。
  1. Lodash 增加了什么?
  • 可用性改进
  • 额外功能
  • 性能提升
  • 链接的简写语法
  • 自定义构建以仅使用您需要的内容
  • 语义版本控制和 100% 的代码覆盖率
于 2014-12-07T12:19:52.743 回答
6

我刚刚发现了一个对我来说很重要的区别。Lodash 的非Underscore.js 兼容版本_.extend()不会复制类级别定义的属性或方法。

我在CoffeeScript中创建了一个Jasmine测试来证明这一点:

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

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

于 2014-12-12T16:56:40.157 回答
4

Lodash 拥有与 Underscore.js_.mapValues()相同的_.mapObject().

于 2015-07-18T17:13:58.243 回答
0

在大多数情况下,Underscore.js 是 Lodash 的子集。

有时,就像现在一样,Underscore.js 会有 Lodash 没有的很酷的小功能,比如 mapObject。这为我的项目开发节省了很多时间。

于 2015-05-14T11:16:42.313 回答
0

它们非常相似,Lodash正在接管......

它们都是一个实用程序库,它采用了 JavaScript 中的实用程序世界......

看起来Lodash现在更新得更频繁了,所以更多地用在最新的项目中......

Lodash似乎也了几个 KB...

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

这是获取数组第一个值的每个文档项的屏幕截图...

下划线.js:

下划线.js

罗达什:

洛达什

由于事情可能会不时更新,请查看他们的网站...

洛达什

下划线.js

于 2019-01-19T06:48:34.973 回答