Lodash 和 Ramda 之间的区别
所以我一直在研究一些关于 JS 框架的知识。据我所知,两个最受欢迎和现代的库是 Lodash 和 Ramda(对吗?)。
我看到一个关于 Lodash 和 Underscore 的类似问题。然而,我没有看到任何与Lodash和Ramda相关的内容。老实说,我也找不到任何基准。
有什么区别?用例怎么样?哪一个更好?
So I've been researching a little bit about JS frameworks. From what I saw, two of the most popular and modern libraries are Lodash and Ramda (right?).
I saw a similar question regarding Lodash and Underscore. However, I didn't see anything related to Lodash and Ramda. Also I couldn't find any benchmark to be honest.
What are the differences? How about the use cases? Which one is better?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
免责声明:我是 Ramda 的创始人和主要维护者之一,所以我确信这个答案会包含一些个人偏见。我会努力不让它失控。
概述
关于问题的这一部分:
这里没有人可以明确回答这个问题。这取决于您的要求、您的历史、您的编程品味以及一百万个甚至更多的模糊因素。
当然,我偏向 Ramda,但我仍然不会尝试告诉您哪一个更好。
但两者之间在能力上存在显着重叠,并且在基本理念上存在显着差异。
两者都是实用功能的抓包,功能之间很少或根本没有内聚力。也就是说,它们是库,而不是框架。他们根本不会尝试确定您如何编写或组织代码。
它们有很多重叠。在当前的 305 个 lodash 函数和当前的 261 个 Ramda 函数中,有 103 个具有共享名称,并且几乎总是具有相似的用途。剩下的函数可能有一半可以在其他库中以不同的名称找到。
简史
尽管之前有一些实验性函数库,但 Underscore 是将其中许多概念带入主流的库JavaScript 的。它曾一度成为该领域无可争议的领导者。
但其性能存在问题。最终 lodash 的创建很大程度上是为了尝试以更好的性能做同样的事情。通过创建
map
等经典函数的自定义版本,而不是默认使用 JS 引擎的内置函数,lodash 很快就超越了 Underscore。但它一开始是作为 Underscore 的简单替代品,并在很长一段时间内保持了这一焦点。Ramda 创始人对 Reginald Braithwaite 的想法印象深刻JavaScript Allongé 并创建了 Ramda 作为教育工具,帮助将这些想法转化为实用的库。他们不太关注性能,而更多地关注干净的 API 和功能组合,以及不可变的数据和无副作用的编码。通过一系列奇怪的事件,它最终变得相当受欢迎。
如今,您很少听说过 Underscore。它仍然在那里,并且仍然使用相当多,但你听不到太多嗡嗡声。对于大多数用户来说,lodash 很好地填补了这个空间。 Ramda 增长很快,但似乎已稳定在 lodash 获得的下载量。但这三个库的功能和使用量都在持续增长,Underscore 和 Ramda 的使用量大致相同,远低于 lodash。
Lodash 有一次创建了一个版本,试图考虑 Ramda 的一些核心问题。我个人从未使用过 lodash-fp 所以我无法谈论如何成功它就是这样做的。
理念
Lodash
Lodash 注重灵活性和性能。正如其创建者曾经描述的,它的重点是
虽然没有通用库可以像自定义编写的代码一样快,但 lodash 已经尽可能接近了。
Lodash 非常灵活。我几年前写
Ramda
Ramda 不太关心性能,更关心简单干净的 API 设计。 Ramda 的想法是,一个函数应该只做一件事,并且应该有一个清晰的接口。 Ramda 的
filter
函数采用谓词函数和可过滤类型的对象,并返回该类型的另一个对象。 (当然,这提出了什么构成可过滤类型的问题,但这是针对其文档的。)Ramda 的重点是使函数的组合变得简单,就像所有数据都是不可变的一样工作,并避免副作用。它还包含其他函数式编程问题,例如提供透镜和使用 FantasyLand 规范。
主要区别
Lodash(忽略 lodash-fp)函数大多首先获取数据,然后是那些对数据起作用的东西,有时后面是改变行为的可选参数。 Ramda 将最不可能改变的论点放在前面,将最有可能改变的论点放在最后。这意味着在数据转换函数中数据是最后的。 Ramda 完全避免可选参数。
Ramda 柯里化了它的所有函数,以及它返回给您的几乎所有函数。 Lodash 有一个 curry 函数,但您需要显式调用它。这是 Ramda 关于函数组合的思想的核心。
Lodash 专注于参考-平等。 Ramda 专注于价值——平等。因此,虽然这些是相似的:
它们的行为非常不同:
这种差异是显着的。 Ramda 的设计更加一致
与功能系统一样,但每当涉及相等性检查时,它都会付出很大的性能代价。对于此类任务,Lodash 可能比 Ramda 快两个数量级。
Ramda 主要设计用于通过组合在短管道或长管道中构建函数。 Lodash 主要设计用于使用命令式代码。您可以使用任一库来完成任一作业,但典型的 Ramda 代码可能如下所示
等效的 lodash 代码可能如下所示
Lodash 对性能的关注意味着它将为任务提供许多经过良好优化的函数。例如,Lodash 具有所有这些函数:
isArguments
、isArray
、isArrayBuffer
、isArrayLike
、isArrayLikeObject
、isBoolean
、isBuffer
、isDate
、isElement
、isEqual
、isEqualWith
、isError
、isFinite
、isFunction
、isInteger
、isLength< /code>,
isMap
,isMatch
,isMatchWith
,isNaN
,isNative
,isNull
、isNumber
、isObject
、isObjectLike
、isPlainObject
、isRegExp< /code>、
isSafeInteger
、isSet
、isString
、isSymbol
、isTypedArray
、isUndefine
、isWeakMap
、isWeakSet
。相比之下,Ramda 希望您为常用函数提供更多参数。它只有
is
、isEmpty
和isNil
。但它是is
句柄几乎所有上述情况,要么通过显式调用:
is (Array, [1, 2, 3])
,要么通过部分应用来创建可重用函数const isArray = is (Array)< /代码>
其中一些差异可能会在 lodash-fp 中消失。但我并没有真正意识到 lodash-fp 是景观的主要部分。对于 lodash 本身,我们可以看到这些库是完全不同的。
性能
该问题询问了基准测试。据我所知,还没有全面的基准测试套件。有趣的是,除了涉及值相等与引用相等的问题外,lodash 在大多数任务上的速度似乎要快 10 - 20%。 Ramda 不像 lodash 那样高度优化,但它是在编写时考虑到性能的,只要满足其他更基本的标准即可。
在那些确实涉及值与引用相等的情况下,lodash 团队可以指出更高的速度,但 Ramda 团队可能会回应说,快速得到错误答案很难说是胜利。
目标受众
Underscore 帮助将函数式编程工具引入了 Javascript。它是一个通用实用程序库,专为任何想要提高工作效率的 JS 开发人员而设计。洛达什继承了这一重点。两者都是以开发人员人体工程学为中心焦点编写的。
Ramda 的受众受到更多限制。它适合那些不仅想要从函数式编程中获取特定工具,而且还想要获取其更基本思想(例如函数纯度和数据不变性)的人。它既针对想要转向更加 FP 风格的 JS 开发人员,也针对那些想要以熟悉的方式使用 JS 的 FP 语言开发人员。它的写作以简单为中心。
总结
这些库在功能上有很多重叠。但他们的设计、基本理念和开发人员经验却截然不同。
如果您在它们之间进行选择,根据上述内容,有一个适合您的正确答案,但没有适合每个人的明确的最佳库。
您还应该考虑是否需要一个。开发自己的可重用函数列表并不难,这些函数可以包含在任何需要它们的项目中。该平台的功能比这些库刚诞生时要强大得多。
Dislaimer: I'm one of the founders and chief maintainers of Ramda, so I'm sure this answer will include some personal bias. I'll try hard not to let it get out of hand.
Overview
As to this part of the question:
There is no way anyone here can answer that definitively. It depends on your requirements, your history, your programming taste, and a million even more fuzzy factors.
I'm biased in favor of Ramda, of course, but I still won't try to tell you which one is better.
But there are significant overlaps in capability between these two and significant differences in underlying philosophy.
Both are grab-bags of utility function, with little or no cohesion between the functions. That is, they are libraries and not frameworks. They don't at all try to determine how you write or organize your code.
They have a great deal of overlap. Among the 305 current lodash functions and the 261 current Ramda ones, there are 103 with shared names, and almost always, similar purpose. Probably half the remaining functions are found in the other library under different names.
A Brief History
Although there were some experimental functional libraries before it, Underscore was the one that brought many of these concepts to the mainstream of Javascript. It stood alone for a while as the undisputed leader in this space.
But there were problems with its performance. Eventually lodash was created in large part to try to do the same thing with better performance. By creating custom versions of classic functions like
map
, rather than defaulting to the JS engine's built-in ones, lodash was quickly able to outperform Underscore. But it started as a drop-in replacement for Underscore, and kept that focus for a long while.The Ramda founders were impressed with the ideas in Reginald Braithwaite's JavaScript Allongé and created Ramda as an educational tool to help turn these ideas into a pragmatic library. They were less focused on performance, and more on a clean API and functional composition, as well as immutable data and side-effect-free coding. Through an odd series of events, it eventually grew quite popular.
These days you don't hear much about Underscore. It's still out there, and still used a fair bit, but you don't hear much buzz. For most users, lodash fills that space well. Ramda grew quickly, but seems to have settled down at about 20 - 25% of the downloads that lodash gets. But all three libraries continue to grow in capability and in usage, with Underscore and Ramda about the same usage, far below lodash.
At one point, lodash created a version that tries to take into account some of Ramda's core concerns. I personally have never used lodash-fp so I can't speak to how successfully it does this.
Philosophy
lodash
Lodash focuses on flexibility and performance. Its focus, as its creator once described, is on
While no general-purpose library can ever be quite as fast as custom-written code, lodash gets as close as possible.
And lodash is flexible. I wrote several years ago
Ramda
Ramda is less concerned with performance, and more with simple and clean API design. The idea for Ramda is that a function should do one thing only, and should have a single clear interface. Ramda's
filter
function takes a predicate function and an object of a filterable type, and returns another object of that type. (Of course this raises the question of what constitutes a filterable type, but that's for its documentation.)Ramda's focus is on making it simple to compose functions, to work as though all data is immutable, and to avoid side-effects. It also incorporates other functional programming concerns, such as supplying lenses and working with the algebraic types of the FantasyLand specification.
Key Differences
Lodash (ignoring lodash-fp) functions mostly take their data first, followed by those things that work on the data, followed sometimes by optional arguments that change the behavior. Ramda puts the arguments least likely to change first, and those most likely to change last. This means that in data-transformation functions the data is last. And Ramda avoid optional arguments altogether.
Ramda curries all its functions, as well as nearly all the functions it returns to you. Lodash has a
curry
function, but you would need to call it explicitly. This is fairly central to Ramda's ideas on function composition.Lodash focuses on reference-equality. Ramda focuses on value-equality. So while these are similar:
these act very differently:
This difference is significant. Ramda's design is more closely aligned
with functional systems, but it comes at a large performance price whenever equality-checking is involved. Lodash is perhaps two orders of magnitude faster than Ramda for such tasks.
Ramda is chiefly designed to build functions through composition, in short or long pipelines. Lodash is chiefly designed to work with imperative code. You can use either library for either job, but typical Ramda code might look like
where the equivalent lodash code might look like
Lodash's focus on performance means that it will supply many well-optimized functions for tasks. For instance, Lodash has all of these functions:
isArguments
,isArray
,isArrayBuffer
,isArrayLike
,isArrayLikeObject
,isBoolean
,isBuffer
,isDate
,isElement
,isEqual
,isEqualWith
,isError
,isFinite
,isFunction
,isInteger
,isLength
,isMap
,isMatch
,isMatchWith
,isNaN
,isNative
,isNull
,isNumber
,isObject
,isObjectLike
,isPlainObject
,isRegExp
,isSafeInteger
,isSet
,isString
,isSymbol
,isTypedArray
,isUndefined
,isWeakMap
,isWeakSet
.Ramda, by contrast expects you to supply more arguments to common functions. It has only
is
,isEmpty
, andisNil
. But it'sis
handlesnearly all the cases above, either by calling explicitly:
is (Array, [1, 2, 3])
or by partially applying to make a reusable functionconst isArray = is (Array)
Some of these differences presumably vanish with lodash-fp. But I don't get any real sense that lodash-fp is a major part of the landscape. And for lodash proper, we can see that the libraries are quite different.
Performance
The question asked about benchmarks. I know of no comprehensive benchmark suite. Anecdotally, it seems except when the issue of value-equality vs reference-equality is involved, lodash is 10 - 20% faster at most tasks. Ramda is not as hyper-optimized as lodash, but it is written with performance in mind, so long as its other more fundamental criteria are met.
In those cases that do involve value-vs-reference equality, the lodash team can point to much higher speeds, but the Ramda team would probably respond that getting the wrong answer quickly is hardly a win.
Target Audience
Underscore helped bring functional programming tools to Javascript. It is a general-purpose utility library, and was designed for any JS developer who wants to be more productive. Lodash inherited this focus. Both are written with developer ergonomics a central focus.
Ramda has a much more restricted audience. It is for those who want to take not just specific tools from functional programming, but who want to take its more fundamental ideas such as functional purity and data immutability. It is aimed both at JS developers who want to move to a more FP style and at those from FP language who want to use JS in a familiar manner. It is written with simplicity a central focus.
Summary
These libraries overlap a great deal in functionality. But their designs, their underlying philosophies, and their developer experience are quite different.
If you're choosing between them, there is a right answer for you, based on the above, but there is no clear definitive best library for everyone.
And you should also consider whether you need one at all. It's not hard to develop your own list of reusable functions to be included in whatever projects need them. The platform has become much more capable than when these libraries were conceived.