Jos*_*rés 28 javascript lodash ramda.js
所以我一直在研究一些关于 JS 框架的知识。据我所知,两个最受欢迎和现代的图书馆是Lodash和Ramda(对吗?)。
我看到了关于 Lodash 和 Underscore 的类似问题。然而,我没有看到任何与Lodash和Ramda相关的内容。老实说,我也找不到任何基准。
有什么区别?用例怎么样?哪一个更好?
Sco*_*yet 86
免责声明:我是 Ramda 的创始人和主要维护者之一,所以我确信这个答案会包含一些个人偏见。我会努力不让事情失控。
\n关于这部分问题:
\n\n\n哪一个更好?
\n
这里没有人可以明确回答这个问题。这取决于您的要求、您的历史、您的编程品味以及一百万个甚至更多的模糊因素。
\n当然,我偏向 Ramda,但我仍然不会尝试告诉您哪一个更好。
\n但两者之间在能力上存在显着重叠,并且在基本理念上存在显着差异。
\n两者都是实用功能的抓包,功能之间很少或根本没有内聚力。也就是说,它们是库而不是框架。他们根本不会尝试确定您如何编写或组织代码。
\n它们有很多重叠。在当前的 305 个 lodash 函数和当前的 261 个 Ramda 函数中,有 103 个具有共享名称,并且几乎总是具有相似的用途。剩下的函数可能有一半可以在其他库中以不同的名称找到。
\n尽管之前有一些实验性函数库,但Underscore是将其中许多概念带入 Javascript 主流的库。它曾一度成为该领域无可争议的领导者。
\n但其性能存在问题。最终lodash的创建很大程度上是为了尝试以更好的性能完成同样的事情。通过创建经典函数(如 )的自定义版本map,而不是默认使用 JS 引擎的内置函数,lodash 很快就超越了 Underscore。但它一开始是作为 Underscore 的简单替代品,并在很长一段时间内保持了这一焦点。
Ramda创始人对 Reginald Braithwaite 的JavaScript Allong\xc3\xa9中的想法印象深刻,并创建了 Ramda 作为教育工具来帮助将这些想法转变为实用的库。他们不太关注性能,而更多地关注干净的 API 和功能组合,以及不可变的数据和无副作用的编码。通过一系列奇怪的事件,它最终变得相当受欢迎。
\n如今您已经很少听说 Underscore 了。它仍然在那里,并且仍然使用了相当多的时间,但你听不到太多嗡嗡声。对于大多数用户来说,lodash 很好地填补了这个空间。Ramda 增长很快,但似乎已经稳定在lodash下载量的 20-25% 左右。但这三个库的功能和使用量都在持续增长,Underscore 和 Ramda 的使用量大致相同,远低于 lodash。
\nLodash 有一次创建了一个版本,试图考虑 Ramda 的一些核心问题。我个人从未使用过lodash-fp,所以我无法评价它的成功程度。
\nLodash 注重灵活性和性能。正如其创建者曾经描述的那样,它的重点是
\n\n\n为尽可能多的开发人员提供高质量的实用方法,重点关注一致性、兼容性、定制和性能。
\n
虽然没有通用库可以像自定义编写的代码一样快,但 lodash 已经尽可能接近了。
\nLodash 非常灵活。我几年前写过
\n\n\n考虑 lodash\'s
\nfilter:它的集合接受数组、对象或字符串,回调接受函数、对象、字符串或什么都不接受,其thisArg. 您将 3 * 4 * 2 = 24 个功能合而为一!
Ramda 不太关心性能,更关心简单干净的 API 设计。Ramda 的想法是,一个函数应该只做一件事,并且应该有一个清晰的接口。Ramda 的filter函数采用谓词函数和可过滤类型的对象,并返回该类型的另一个对象。(当然,这提出了什么构成可过滤类型的问题,但这是针对其文档的。)
Ramda 的重点是使函数的组合变得简单,就像所有数据都是不可变的一样工作,并避免副作用。它还包含其他函数式编程问题,例如提供镜头和使用FantasyLand 规范的代数类型。
\nLodash(忽略 lodash-fp)函数大多首先获取数据,然后是那些对数据起作用的东西,有时后面是改变行为的可选参数。Ramda 将最不可能改变的论点放在前面,将最有可能改变的论点放在最后。这意味着在数据转换函数中数据是最后的。Ramda 完全避免了可选参数。
\nRamda 柯里化了它的所有函数,以及它返回给你的几乎所有函数。Lodash 有一个curry函数,但您需要显式调用它。这是 Ramda 函数组合思想的核心。
Lodash 专注于引用相等。Ramda 注重价值平等。虽然这些是相似的:
\n// lodash\n_.union ([1, 2, 3, 4, 5], [2, 3, 5, 7, 11]) //=> [1, 2, 3, 4, 5, 7, 11]\n_.intersection ([1, 2, 3, 4, 5], [2, 3, 5, 7, 11]) //=> [2, 3, 5]\n\n// Ramda\nR.union ([1, 2, 3, 4, 5], [2, 3, 5, 7, 11]) //=> [1, 2, 3, 4, 5, 7, 11]\nR.intersection ([1, 2, 3, 4, 5], [2, 3, 5, 7, 11]) //=> [2, 3, 5]\nRun Code Online (Sandbox Code Playgroud)\n它们的行为非常不同:
\n// lodash\n_.union (\n [{x: 1}, {x: 2}, {x: 3}, {x: 4}, {x: 5}], \n [{x: 2}, {x: 3}, {x: 5}, {x: 7}, {x: 11}]\n)\n//=> [{x: 1}, {x: 2}, {x: 3}, {x: 4}, {x: 5}, {x: 2}, {x: 3}, {x: 5}, {x: 7}, {x: 11}]\n_.intersection (\n [{x: 1}, {x: 2}, {x: 3}, {x: 4}, {x: 5}], \n [{x: 2}, {x: 3}, {x: 5}, {x: 7}, {x: 11}]\n) //=> []\n\n// Ramda\nR.union (\n [{x: 1}, {x: 2}, {x: 3}, {x: 4}, {x: 5}], \n [{x: 2}, {x: 3}, {x: 5}, {x: 7}, {x: 11}]\n)\n//=> [{x: 1}, {x: 2}, {x: 3}, {x: 4}, {x: 5}, {x: 7}, {x: 11}]\nR.intersection (\n [{x: 1}, {x: 2}, {x: 3}, {x: 4}, {x: 5}], \n [{x: 2}, {x: 3}, {x: 5}, {x: 7}, {x: 11}]\n) //=> [x: 2}, {x: 3}, {x: 5}]\nRun Code Online (Sandbox Code Playgroud)\n这种差异是显着的。Ramda 的设计与功能系统更紧密地结合在一起,但只要涉及相等性检查,它就会付出很大的性能代价。对于此类任务,Lodash 可能比 Ramda 快两个数量级。
\nRamda 主要设计用于通过组合在短管道或长管道中构建函数。Lodash 主要设计用于使用命令式代码。您可以使用任一库来完成任一工作,但典型的 Ramda 代码可能如下所示
\nconst myFn = R.pipe (\n R.fn1,\n R.fn2 (\'arg1\', \'arg2\'),\n R.fn3 (\'arg3\'),\n R.fn4\n)\nRun Code Online (Sandbox Code Playgroud)\n等效的 lodash 代码可能如下所示
\nconst myFn = (x, y) => {\n const var1 = _.fn1 (x, y)\n const var2 = _.fn2 (var1, \'arg1\', \'arg2\')\n const var3 = _.fn3 (var2, \'arg3\')\n return _.fn4 (var3)\n}\nRun Code Online (Sandbox Code Playgroud)\nLodash 对性能的关注意味着它将为任务提供许多优化良好的功能。例如,Lodash 具有所有这些功能:, 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 期望您为常用函数提供更多参数。它只有is、isEmpty、 和isNil。但它可以is通过显式调用来处理\n几乎所有上述情况:is (Array, [1, 2, 3])或者通过部分应用来创建可重用函数const isArray = is (Array)
其中一些差异可能会在 lodash-fp 中消失。但我并没有真正意识到 lodash-fp 是景观的主要部分。对于 lodash 本身,我们可以看到这些库有很大不同。
\n该问题询问了基准。据我所知,还没有全面的基准测试套件。有趣的是,除了涉及值相等与引用相等的问题外,lodash 在大多数任务上的速度似乎要快 10 - 20%。Ramda 不像 lodash 那样高度优化,但它是在编写时考虑到性能的,只要满足其他更基本的标准即可。
\n在那些确实涉及值与引用相等的情况下,lodash 团队可以指出更高的速度,但 Ramda 团队可能会回应说,快速得到错误答案很难说是胜利。
\nUnderscore 帮助将函数式编程工具引入了 Javascript。它是一个通用实用程序库,专为任何想要提高工作效率的 JS 开发人员而设计。洛达什继承了这一重点。两者都是以开发人员人体工程学为中心焦点编写的。
\nRamda 的受众受到更多限制。它适合那些不仅想要从函数式编程中获取特定工具,而且还想要获取其更基本思想(例如函数纯度和数据不变性)的人。它既针对想要转向更加 FP 风格的 JS 开发人员,也针对那些想要以熟悉的方式使用 JS 的 FP 语言开发人员。它以简单性为中心焦点。
\n这些库在功能上有很多重叠。但他们的设计、基本理念和开发人员经验却截然不同。
\n如果您在它们之间进行选择,根据上述内容,有一个适合您的正确答案,但没有适合每个人的明确的最佳库。
\n您还应该考虑是否需要一个。开发自己的可重用函数列表并不难,这些函数可以包含在任何需要它们的项目中。该平台的功能比这些库刚诞生时要强大得多。
\n