Javascript lodash 和下划线的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13789618/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Differences between lodash and underscore
提问by Brian M. Hunt
Why would someone prefer either the lodash.jsor underscore.jsutility library over the other?
为什么有人更喜欢lodash.js或underscore.js实用程序库?
Lodash seems to be a drop-in replacement for underscore, the latter having been around longer.
Lodash 似乎是下划线的替代品,后者已经存在的时间更长了。
I think both are brilliant, but I do not know enough about how they work to make an educated comparison, and I would like to know more about the differences.
我认为两者都很出色,但我对它们的工作原理知之甚少,无法进行有根据的比较,我想更多地了解它们之间的差异。
回答by John-David Dalton
I created Lo-Dash to provide more consistent cross-environment iteration support for arrays, strings, objects, and argumentsobjects1. It has since become a superset of Underscore, providing more consistent API behavior, more features(like AMD support, deep clone, and deep merge), more thorough documentationand unit tests (tests which run in Node, Ringo, Rhino, Narwhal, PhantomJS, and browsers), better overall performance and optimizations for large arrays/object iteration, and more flexibility with custom buildsand template pre-compilation utilities.
我创建了 Lo-Dash 来为数组、字符串、对象和arguments对象1提供更一致的跨环境迭代支持。它已成为 Underscore 的超集,提供更一致的 API 行为、更多功能(如 AMD 支持、深度克隆和深度合并)、更全面的文档和单元测试(在 Node、Ringo、Rhino、Narwhal、PhantomJS 中运行的测试)和浏览器)、更好的整体性能和大型数组/对象迭代的优化,以及自定义构建和模板预编译实用程序的更大灵活性。
Because Lo-Dash is updated more frequently than Underscore, a lodash underscorebuild is providedto ensure compatibility with the latest stable version of Underscore.
由于 Lo-Dash 的更新频率高于 Underscore,因此提供了一个lodash underscore构建版本以确保与 Underscore 的最新稳定版本兼容。
At one point I was even given push accessto Underscore, in part because Lo-Dash is responsible for raising more than 30 issues; landing bug fixes, new features, & perf gains in Underscore v1.4.x+.
有一次,我什至获得了 Underscore 的推送访问权限,部分原因是 Lo-Dash 负责提出 30 多个问题;在 Underscore v1.4.x+ 中登陆错误修复、新功能和性能提升。
In addition there are at least 3 Backbone boilerplates that include Lo-Dash by default and Lo-Dash is now mentioned in Backbone's official documentation.
此外,至少有 3 个 Backbone 样板默认包含 Lo-Dash,现在 Backbone 的官方文档中提到了 Lo-Dash 。
Check out Kit Cambridge's post, Say "Hello" to Lo-Dash, for a deeper breakdown on the differences between Lo-Dash and Underscore.
查看 Kit Cambridge 的帖子,向 Lo-Dash 说“你好”,更深入地了解 Lo-Dash 和 Underscore 之间的差异。
Footnotes:
脚注:
- Underscore has inconsistent support for arrays, strings, objects, and
argumentsobjects. In newer browsers, Underscore methods ignore holes in arrays, "Objects" methods iterateargumentsobjects, strings are treated as array-like, and methods correctly iterate functions (ignoring their "prototype" property) and objects (iterating shadowed properties like "toString" and "valueOf"), while in older browsers they will not. Also, Underscore methods like_.clonepreserve holes in arrays, while others like_.flattendon't.
- Underscore 对数组、字符串、对象和
arguments对象的支持不一致。在较新的浏览器中,Underscore 方法忽略数组中的漏洞,“Objects”方法迭代arguments对象,字符串被视为类数组,并且方法正确迭代函数(忽略它们的“prototype”属性)和对象(迭代像“toString”和"valueOf"),而在较旧的浏览器中则不会。此外,Underscore 方法喜欢_.clone保留数组中的空洞,而其他方法_.flatten则不这样做。
回答by neiker
Lo-Dash is inspired by underscore, but nowadays is superior solution. You can make your custom builds, have a higher performance, support AMD and have great extra features. Check this Lo-Dash vs Underscore benchmarkson jsperf and.. this awesome post about lo-dash:
Lo-Dash 的灵感来自下划线,但现在是出色的解决方案。您可以进行自定义构建,获得更高的性能,支持 AMD 并拥有出色的额外功能。检查jsperf 上的Lo-Dash 与Underscore基准测试以及 .. 这篇关于 lo-dash 的精彩帖子:
One of the most useful feature when you work with collections, is the shorthand syntax:
使用集合时最有用的功能之一是速记语法:
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 }]
(taken from lodash docs)
(取自lodash 文档)
回答by Iest
If like me you were expecting a list of usage differences between underscore and lodash, there's a guide for migrating from underscore to lodash.
如果像我一样,你期待下划线和 lodash 之间的使用差异列表,有一个从下划线迁移到 lodash 的指南。
Here's the current state of it for posterity:
这是后代的当前状态:
- Underscore
_.anyis Lodash_.some- Underscore
_.allis Lodash_.every- Underscore
_.composeis Lodash_.flowRight- Underscore
_.containsis Lodash_.includes- Underscore
_.eachdoesn't allow exiting by returningfalse- Underscore
_.findWhereis Lodash_.find- Underscore
_.flattenis deep by default while Lodash is shallow- Underscore
_.groupBysupports an iteratee that is passed the parameters(value, index, originalArray), while in Lodash, the iteratee for_.groupByis only passed a single parameter:(value).- Underscore
_.indexOfwith 3rd parameterundefinedis Lodash_.indexOf- Underscore
_.indexOfwith 3rd parametertrueis Lodash_.sortedIndexOf- Underscore
_.indexByis Lodash_.keyBy- Underscore
_.invokeis Lodash_.invokeMap- Underscore
_.mapObjectis Lodash_.mapValues- Underscore
_.maxcombines Lodash_.max&_.maxBy- Underscore
_.mincombines Lodash_.min&_.minBy- Underscore
_.samplecombines Lodash_.sample&_.sampleSize- Underscore
_.objectcombines Lodash_.fromPairsand_.zipObject- Underscore
_.omitby a predicate is Lodash_.omitBy- Underscore
_.pairsis Lodash_.toPairs- Underscore
_.pickby a predicate is Lodash_.pickBy- Underscore
_.pluckis Lodash_.map- Underscore
_.sortedIndexcombines Lodash_.sortedIndex&_.sortedIndexOf- Underscore
_.uniqby aniterateeis Lodash_.uniqBy- Underscore
_.whereis Lodash_.filter- Underscore
_.isFinitedoesn't align withNumber.isFinite
(e.g._.isFinite('1')returnstruein Underscore butfalsein Lodash)- Underscore
_.matchesshorthand doesn't support deep comparisons
(e.g._.filter(objects, { 'a': { 'b': 'c' } }))- Underscore ≥ 1.7 & Lodash
_.templatesyntax is_.template(string, option)(data)- Lodash
_.memoizecaches areMaplike objects- Lodash doesn't support a
contextargument for many methods in favor of_.bind- Lodash supports implicit chaining, lazy chaining, & shortcut fusion
- Lodash split its overloaded
_.head,_.last,_.rest, &_.initialout into_.take,_.takeRight,_.drop, &_.dropRight
(i.e._.head(array, 2)in Underscore is_.take(array, 2)in 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- 下划线
_.uniq由iteratee是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 中)
回答by kumarharsh
In addition to John's answer, and reading up on lodash (which I had hitherto regarded as a "me-too" to underscore), and seeing the performance tests, reading the source-code, and blog posts, the few points which make lodash much superior to underscore are these:
除了约翰的回答,阅读 lodash(我一直认为这是一个“我也喜欢”强调),并查看性能测试,阅读源代码和博客文章,使 lodash 的几点优于下划线的是这些:
It's not about the speed, as it is about consistencyof speed (?)
If you look into underscore's source-code, you'll see in the first few lines that underscore falls-back on the native implementations of many functions. Although in an ideal world, this would have been a better approach, if you look at some of the perf links given in these slides, it is not hard to draw the conclusion that the quality of those 'native implementations' vary a lot browser-to-browser. Firefox is damn fast in some of the functions, and in some Chrome dominates. (I imagine there would be some scenarios where IE would dominate too). I believe that it's better to prefer a code whose performanceis more consistent across browsers.
Do read the blog post earlier, and instead of believing it for its sake, judge for yourself by running the benchmarks. I am stunned right now, seeing a lodash performing 100-150% faster than underscore in even simple, nativefunctions such as
Array.everyin Chrome!The extrasin lodash are also quite useful.
- As for Xananax's highly upvoted comment suggesting contribution to underscore's code: It's always better to have GOODcompetition, not only does it keep innovation going, but also drives you to keep yourself (or your library) in good shape.
这不是关于速度,而是关于速度的一致性(?)
如果您查看 underscore 的源代码,您将在前几行看到下划线回退到许多函数的本机实现。尽管在理想的世界中,这会是一种更好的方法,但如果您查看这些幻灯片中给出的一些性能链接,不难得出结论,即这些“本机实现”的质量与浏览器的差异很大-到浏览器。Firefox 在某些功能上非常快,而在某些 Chrome 中占主导地位。(我想在某些情况下 IE 也会占主导地位)。我认为最好选择性能在浏览器间更一致的代码。
一定要早点阅读博客文章,不要相信它,而是通过运行基准来判断自己。我惊呆了,现在,眼看执行除下划线快100-150%,甚至一个lodash简单,原生功能,如
Array.everyChrome浏览器!lodash 中的附加功能也非常有用。
- 至于 Xananax 的高度赞成的评论建议对 underscore 的代码做出贡献:拥有良好的竞争总是更好,它不仅可以保持创新,还可以驱使您保持自己(或您的图书馆)的良好状态。
Here is a list of differencesbetween lodash, and it's underscore-build is a drop-in replacement for your underscore projects.
这是lodash 之间的差异列表,它的 underscore-build 是下划线项目的替代品。
回答by Lukas Bünger
This is 2014 and a couple of years too late. Still I think my point holds:
现在是 2014 年,已经晚了几年。我仍然认为我的观点是成立的:
IMHO this discussion got blown out of proportion quite a bit. Quoting the aforementioned blog post:
恕我直言,这个讨论有点过分了。引用上述博客文章:
Most JavaScript utility libraries, such as Underscore, Valentine, and wu, rely on the “native-first dual approach.” This approach prefers native implementations, falling back to vanilla JavaScript only if the native equivalent is not supported. But jsPerf revealed an interesting trend: the most efficient way to iterate over an array or array-like collection is to avoid the native implementations entirely, opting for simple loops instead.
大多数 JavaScript 实用程序库,例如 Underscore、Valentine 和 wu,都依赖于“本地优先的双重方法”。这种方法更喜欢本机实现,只有在不支持本机等效项时才回退到 vanilla JavaScript。但是 jsPerf 揭示了一个有趣的趋势:迭代数组或类数组集合的最有效方法是完全避免本机实现,而是选择简单的循环。
As if "simple loops" and "vanilla Javascript" are more native than Array or Object method implementations. Jeez ...
好像“简单循环”和“vanilla Javascript”比数组或对象方法实现更原生。天啊...
It certainly would be nice to have a single source of truth, but there isn't. Even if you've been told otherwise, there is no Vanilla God, my dear. I'm sorry. The only assumption that really holds is that we are all writing Javascript code that aims at performing well in all major browsers, knowing that all of them have different implementations of the same things. It's a bitch to cope with, to put it mildly. But that's the premise, whether you like it or not.
拥有单一的真相来源当然很好,但事实并非如此。即使有人告诉你,也没有香草之神,亲爱的。抱歉。唯一真正成立的假设是,我们都在编写旨在在所有主要浏览器中表现良好的 Javascript 代码,并且知道所有浏览器对相同的事物都有不同的实现。说得客气一点,这是个婊子。但这是前提,不管你喜不喜欢。
Maybe y'all are working on large scale projects that need twitterish performance so that you really see the difference between 850,000 (underscore) vs. 2,500,000 (lodash) iterations over a list per secright now!
也许你们都在从事需要 twitterish 性能的大型项目,以便您现在真正看到每秒列表中 850,000(下划线)与 2,500,000(lodash)迭代之间的差异!
I for one am not. I mean, I worked projects where I had to address performance issues, but they were never solved or caused by neither Underscore nor Lo-Dash. And unless I get hold of the real differences in implementation and performance (we're talking C++ right now) of lets say a loop over an iterable (object or array, sparse or not!), I rather don't get bothered with any claims based on the results of a benchmark platform that is already opinionated.
我不是。我的意思是,我从事过一些必须解决性能问题的项目,但这些问题从来没有被 Underscore 和 Lo-Dash 解决或引起过。除非我掌握了实现和性能(我们现在谈论的是 C++)的真正差异,让我们说一个可迭代的循环(对象或数组,稀疏与否!),我宁愿不打扰任何声明基于已经固执己见的基准平台的结果。
It only needs one single update of lets say Rhino to set its Array method implementations on fire in a fashion that not a single "medieval loop methods perform better and forever and whatnot" priest can argue his/her way around the simple fact that all of a sudden array methods in FF are much faster than his/her opinionated brainfwor. Man, you just can't cheat your runtime environment by cheating your runtime environment! Think about that when promoting ...
它只需要一次更新,比如 Rhino 就可以以一种方式将其 Array 方法实现设置为火,没有一个“中世纪循环方法表现得更好,永远等等”牧师可以围绕一个简单的事实争论他/她的方式,即所有FF 中的突然数组方法比他/她自以为是的脑残要快得多。伙计,你不能通过欺骗你的运行时环境来欺骗你的运行时环境!推广的时候想想...
your utility belt
你的实用腰带
... next time.
... 下次。
So to keep it relevant:
因此,要保持相关性:
- Use Underscore if you're into convenience without sacrificing native ish.
- Use Lo-Dash if you're into convenience and like its extended feature catalogue (deep copy etc.) and if you're in desperate need of instant performance and most importantly don't mind settling for an alternative as soon as native API's outshine opinionated workaurounds. Which is going to happen soon. Period.
- There's even a third solution. DIY! Know your environments. Know about inconsistencies. Read their (John-David's and Jeremy's) code. Don't use this or that without being able to explain why a consistency/compatibility layer is really needed and enhances your workflow or improves the performance of your app. It is very likely that your requirements are satisfied with a simple polyfill that you're perfectly able to write yourself. Both libraries are just plain vanilla with a little bit of sugar. They both just fight over who's serving the sweetest pie. But believe me, in the end both are only cooking with water. There's no Vanilla God so there can't be no Vanilla pope, right?
- 如果您在不牺牲本机 ish 的情况下使用方便,请使用下划线。
- 如果您喜欢使用 Lo-Dash 方便并且喜欢它的扩展功能目录(深度复制等),并且如果您迫切需要即时性能,最重要的是不要介意在原生 API 一枝独秀时尽快找到替代方案自以为是的解决方法。这很快就会发生。时期。
- 甚至还有第三种解决方案。DIY!了解您的环境。了解不一致。阅读他们(John-David和Jeremy的)代码。不要在无法解释为什么真正需要一致性/兼容性层并增强您的工作流程或提高应用程序性能的情况下使用这个或那个。很可能您的需求可以通过一个您完全能够自己编写的简单 polyfill 来满足。这两个库都只是加了一点糖的普通香草。他们都在为谁提供最甜的馅饼而争吵。但相信我,最终两者都只是用水做饭。没有香草神,所以不可能没有香草教皇,对吧?
Choose whatever approach fits your needs the most. As usual. I'd prefer fallbacks on actual implementations over opinionated runtime cheats anytime but even that seems to be a matter of taste nowadays. Stick to quality resources like http://developer.mozilla.comand http://caniuse.comand you'll be just fine.
选择最适合您需求的方法。照常。我更喜欢在任何时候对实际实现进行回退,而不是固执的运行时作弊,但即使现在这似乎也是一个品味问题。坚持使用http://developer.mozilla.com和http://caniuse.com等优质资源,你会没事的。
回答by David Dal Busco
I'm agree with most of things said here but I just want to point out an argument in favor of underscore.js: the size of the library.
我同意这里所说的大部分内容,但我只想指出一个支持 underscore.js 的论点:库的大小。
Specially in case you are developing an app or website which intend to be use mostly on mobile devices, the size of the resulting bundle and the effect on the boot or download time may have an important role.
特别是如果您正在开发主要在移动设备上使用的应用程序或网站,则生成的包的大小以及对启动或下载时间的影响可能具有重要作用。
For comparison, these sizes are those I noticed with source-map-explorer after running ionic serve:
为了比较,这些尺寸是我在运行 ionic serve 后使用 source-map-explorer 注意到的尺寸:
lodash: 523kB
underscore.js: 51.6kb
edited Feb 2020:
2020 年 2 月编辑:
one can use BundlePhobiato check the current size of Lo-Dashand Underscore
人们可以使用BundlePhobia检查的当前大小罗短跑和下划线
回答by qbolec
Not sure if that is what OP meant, but I came accross this question because I was searching for a list of issues I have to keep in mind when migrating from underscore to lodash.
不确定这是否是 OP 的意思,但我遇到了这个问题,因为我正在寻找从下划线迁移到 lodash 时必须牢记的问题列表。
I would really appreciate if someone posted an article with a complete list of such differences. Let me start with the things I've learned the hard way (that is, things which made my code explode on production:/) :
如果有人发布包含此类差异的完整列表的文章,我将不胜感激。让我从我艰难地学到的东西开始(也就是说,让我的代码在生产中爆炸的东西:/):
_.flattenin underscore is deep by default and you have to pass true as second argument to make it shallow. In lodash it is shallow by default and passing true as second argument will make it deep! :)_.lastin underscore accepts a second argument which tells how many elements you want. Inlodashthere is no such option. You can emulate this with.slice_.first(same issue)_.templatein underscore can be used in many ways, one of which is providing the template string and data and gettingHTMLback (or at least that's how it worked some time ago). Inlodashyou receive a function which you should then feed with the data._(something).map(foo)works in underscore, but in lodash I had to rewrite it to_.map(something,foo). Perhaps that was just aTypeScript-issue
_.flatten默认情况下,下划线很深,您必须将 true 作为第二个参数传递以使其变浅。在 lodash 中,默认情况下它是浅的,传递 true 作为第二个参数会使它变深!:)_.last下划线接受第二个参数,它告诉你想要多少个元素。在lodash没有这样的选择。你可以模仿这个.slice_.first(同样的问题)_.templatein underscore 可以以多种方式使用,其中之一是提供模板字符串和数据并HTML返回(或者至少在一段时间前它是这样工作的)。在lodash你收到一个函数,然后你应该用数据提供它。_(something).map(foo)在下划线中工作,但在 lodash 中我不得不将它重写为_.map(something,foo). 也许那只是一个TypeScript问题
回答by pilau
http://benmccormick.org/2014/11/12/underscore-vs-lodash/
http://benmccormick.org/2014/11/12/underscore-vs-lodash/
Latest article comparing the two by Ben McCormick:
本·麦考密克 (Ben McCormick) 比较两者的最新文章:
Lo-Dash's API is a superset of Underscore's.
Under the hood [Lo-Dash] has been completely rewritten.
Lo-Dash is definitely not slower than Underscore.
What has Lo-Dash added?
- Usability Improvements
- Extra Functionality
- Performance Gains
- Shorthand syntaxes for chaining
- Custom Builds to only use what you need
- Semantic versioning and 100% code coverage
Lo-Dash 的 API 是 Underscore 的超集。
在引擎盖下 [Lo-Dash] 已完全重写。
Lo-Dash 绝对不比 Underscore 慢。
Lo-Dash 添加了什么?
- 可用性改进
- 额外功能
- 性能提升
- 链接的速记语法
- 自定义构建只使用你需要的
- 语义版本控制和 100% 的代码覆盖率
回答by Craig Walker
I just found one difference that ended up being important for me. The non-underscore-compatible version of lodash's _.extend()does notcopy over class-level-defined properties or methods.
我刚刚发现了一个最终对我很重要的差异。lodash的的非下划线兼容的版本_.extend()并没有拷贝过来的类级定义的属性或方法。
I've created a Jasmine test in CoffeeScript that demonstrates this:
我在 CoffeeScript 中创建了一个 Jasmine 测试来演示这一点:
https://gist.github.com/softcraft-development/1c3964402b099893bd61
https://gist.github.com/softcraft-development/1c3964402b099893bd61
Fortunately, lodash.underscore.jspreserves Underscore's behaviour of copying everything, which for my situation was the desired behaviour.
幸运的是,lodash.underscore.js保留了 Underscore 复制所有内容的行为,这对于我的情况是所需的行为。
回答by artknight
lodashhas got _.mapValues()which is identical to underescore's _.mapObject().
lodash得到了_.mapValues()与下划线相同的_.mapObject().

