lodash和下划线之间的差异

Bri*_*unt 1566 javascript underscore.js lodash

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

Lodash似乎是下划线的替代品,后者已经存在了更长时间.

我认为两者都很精彩,但我对他们如何努力进行有根据的比较并不了解,我想更多地了解这些差异.

Joh*_*ton 1972

我创建了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,现在Backbone的官方文档中提到了Lo-Dash .

查看Kit Cambridge的帖子,向Lo-Dash说"你好",以便更深入地分析Lo-Dash和Underscore之间的差异.

脚注:

  1. Underscore对数组,字符串,对象和arguments对象的支持不一致.在较新的浏览器中,Underscore方法忽略数组中的漏洞,"Objects"方法迭代arguments对象,字符串被视为类似数组,方法正确迭代函数(忽略它们的"原型"属性)和对象(迭代阴影属性,如"toString"和"valueOf"),而在较旧的浏览器中他们不会.此外,Underscore方法,如_.clone保留数组中的漏洞,而其他人喜欢_.flatten不这样做.

  • 我喜欢lo-dash而且我正在使用它,所以请不要认为我在抨击,但为什么不贡献下划线而不是创建一个新的库? (185认同)
  • @Brian - 在开发Lo-Dash的过程中,我继续提出这样一个问题:"在Lo-Dash中,有什么人能指出,与Underscore相比,这是一个负面因素?" 然后解决它们.这就是为什么我加强了文档,添加了自定义构建,并使源更具可读性. (168认同)
  • @Xananax - 检查评论主题:https://github.com/jashkenas/underscore/commit/4e4bc194c0a0e06aa8f7633695ad10030d871a2b - 这可能会回答这个问题. (125认同)
  • 有没有努力将lodash合并回下划线? (40认同)
  • 我很想发布一些基准测试,但这可能会变得单调乏味.可以说,我运行的每个基准测试都证明Lo-Dash比下划线更快(在许多情况下_MUCH_更快). (10认同)
  • 谢谢你的回答,约翰 - 大卫,你的想法非常感谢.你是否认为可以说lodash实际上总是更倾向于强调?(更好的问题:你能想到任何不同意这种主张的人吗?)非常感谢. (5认同)
  • @AlexMills lodash用lodash-fp覆盖. (4认同)
  • @Shanimal:Backbone需要下划线.不使用下划线,样板文件想要使用lodash作为替代品,因此它将"下划线"路径设置为指向您的lodash位置. (2认同)
  • 此外,我还发现 lodash 和 underscore 的 `_.union` 函数的不同之处在于 `underscore.union([], 3) === [3]` 和 `lodash.union([], 3) ) === []` (2认同)
  • Lo-Dash 3.0将支持Lazy Evaluation,而Underscore则不支持.阅读更多:http://filimanjaro.com/blog/2014/introducing-lazy-evaluation/ (2认同)
  • @streetlight:**[现在有](https://github.com/jashkenas/underscore/issues/2182)**(或者反过来?) (2认同)
  • **[underdash](https://github.com/underdash/underdash)**计划正在进行中! (2认同)
  • 为什么不直接修补下划线 XD (2认同)
  • 看看引用的文章 - 对Lo-Dash说"Hello","本地优先的双重方法."这种方法更喜欢本机实现,只有在不支持本机等效时才会回归到vanilla JavaScript.我很困惑,本机和香草JavasScript有什么区别? (2认同)

nei*_*ker 184

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 }]
Run Code Online (Sandbox Code Playgroud)

(摘自lodash docs)

  • 2012年https://github.com/jashkenas/underscore/issues/648(其名称为`where`)的下划线中的`filter`功能 (7认同)
  • `characters.filter(x=>x.age==36) //纯js` (3认同)

Ies*_*est 80

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

以下是后人的当前状态:

  • 下划线_.any是Lodash_.some
  • 下划线_.all是Lodash_.every
  • 下划线_.compose是Lodash_.flowRight
  • 下划线_.contains是Lodash_.includes
  • 下划线_.each是Lodashfalse
  • 下划线_.findWhere是Lodash_.find
  • 下划线_.flatten是Lodash_.groupBy
  • 下划线(value, index, originalArray)是Lodash_.groupBy
  • 下划线(value)是Lodash_.indexOf
  • Underscore undefined不允许退货_.indexOf
  • 下划线_.indexOf是深默认,而Lodash浅
  • 下划线true不对齐_.sortedIndexOf
    (如_.indexBy返回_.keyBy的下划线,但_.invoke在Lodash)
  • 下划线_.invokeMap速记不支持深度比较
    (例如_.mapObject)
  • Underscore≥1.7&Lodash已将其_.mapValues语法更改为
    _.max
  • Lodash _.max不接受_.maxBy像Underscore 那样的功能.使用Lodash_.min
  • Lodash _.min_.minBy不接受一个_.sample像下划线的说法.使用_.sample
  • Lodash _.sampleSize缓存_.object就像对象
  • Lodash支持隐式链接,懒惰链接和快捷方式融合
  • Lodash拆分它的过载_.fromPairs,_.zipObject,_.omit,和_.omitBy伸到
    _.pairs,_.toPairs,_.pick,和 _.pickBy
    (即_.pluck在下划线是 _.map在Lodash)


kum*_*rsh 60

除了John的答案,还读起lodash(我迄今为止被认为是"me-too"强调),并看到性能测试,阅读源代码和博客帖子,这些内容使得lodash这些更优于下划线:

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

    如果你看一下下划线的源代码,你会在前几行中看到下划线回落到许多函数的本机实现上.虽然在一个理想的世界中,这可能是一种更好的方法,如果你看一下这些幻灯片中给出的一些性能链接,不难得出这些"本机实现"的质量变化很大的结论 -到浏览器.Firefox的某些功能非常快,而且在一些Chrome中占主导地位.(我想有一些情况下IE也会占据主导地位).我认为最好选择性能在浏览器中更加一致的代码.

    请先阅读博客文章,而不是相信它本身,通过运行基准来判断自己.我惊呆了,现在,眼看执行比甚至强调快100-150%一lodash 简单,原生功能,如Array.everyChrome浏览器!

  2. lodash中的附加功能也非常有用.

  3. 至于Xananax的高度评价意见表明对下划线代码的贡献:拥有良好的竞争总是更好,不仅是它继续创新,而且还促使你保持自己(或你的图书馆)的良好状态.

以下是lodash之间的差异列表,它的下划线构建是您的下划线项目的直接替代品.

  • 在哪种情况下,"速度的一致性"值?假设我有一个在FF和IE中速度为100%的方法,本机实现的IE速度为80%,FF为120%(反之亦然).然后我会说在FF中使用本机实现和IE中自己的实现会很好.我无法想象任何情况,我会说:让我们放慢速度只是因为它有与IE中相同的速度.代码的大小和可维护性或所有浏览器的平均减速都是参数,但速度的一致性? (6认同)
  • 我倾向于回退到浏览器的原生实现,因为在大多数情况下它具有可接受的性能并且可以通过浏览器更新来改进而无需担心使库保持最新. (5认同)
  • @KumarHarsh也许我没说好.我的意思是我倾向于使用内部使用本机函数的库(如果可用),而不是总是更喜欢自己的实现. (3认同)
  • 我的意思是,"始终加快速度" (2认同)

Luk*_*ger 43

这是2014年,而且已经太晚了几年.我仍然认为我的观点是:

恕我直言,这次讨论相当不成比例.引用上述博文:

大多数JavaScript实用程序库(例如Underscore,Valentine和wu)都依赖于"本机优先的双重方法".这种方法更喜欢本机实现,只有在不支持本机等效时才会回归到vanilla JavaScript.但jsPerf揭示了一个有趣的趋势:迭代数组或类似数组的最有效方法是完全避免本机实现,而选择简单的循环.

好像"简单循环"和"vanilla Javascript"比Array或Object方法实现更本地化.Jeez ......

拥有单一的事实来源肯定会很好,但事实并非如此.即使你已经被告知,亲爱的,也没有香草神.对不起.唯一真正成立的假设是我们都在编写旨在在所有主流浏览器中都表现良好的Javascript代码,因为他们知道所有这些代码都有不同的实现.温和地说,这是一个应对的婊子.但这是前提,无论你喜不喜欢.

也许你们都在开展大规模的项目,这些项目需要慌张的表现才能让你真正看到每秒在列表上的850,000(下划线)和2,500,000(lodash)迭代之间的差异!

我不是一个人.我的意思是,我工作的项目我必须解决性能问题,但它们从未解决或由Underscore和Lo-Dash引起.除非我抓住实现和性能的真正差异(我们现在正在谈论C++),让我们说一个循环遍及一个可迭代的(对象或数组,稀疏或不稀疏!),我宁愿不被任何困扰基于已经舆论的基准平台的结果提出索赔.

它只需要一个单独的更新,让我们说Rhino以一种方式设置它的Array方法实现,而不是一个单独的"中世纪循环方法表现更好,永远而且什么都不是"牧师可以围绕这个简单的事实争论他/她的方式FF中的突然阵列方法比他/她认为的脑力快得多.伙计,你不能通过欺骗你的运行时环境来欺骗你的运行时环境!在推广时考虑一下......

你的实用腰带

... 下次.

所以要保持相关性:

  • 如果您在不牺牲原生能力的情况下进入方便,请使用Underscore.
  • 使用Lo-Dash,如果你是方便的,并且喜欢它的扩展功能目录(深层拷贝等),如果你迫切需要即时性能,最重要的是不要介意在本机API出现时立即寻求替代方案固执己见的工作.哪个会很快发生.期.
  • 甚至还有第三种解决方案.DIY!了解您的环境.了解不一致.阅读他们(约翰 - 大卫杰里米的)代码.如果不能解释为什么真正需要一致性/兼容性层并且增强您的工作流程或提高应用程序的性能,请不要使用这个或那个.很可能您的要求满足于您完全能够自己编写的简单的填充物.这两个图书馆都是普通的香草,带有一点点糖.他们俩只是为谁最甜蜜的馅饼而战.但相信我,最后两人都只是用水做饭.没有香草神,所以不可能没有香草教皇,对吗?

选择最适合您需求的方法.照常.我更喜欢在实际的实现上回落而不是固执的运行时作弊,但即便如此,这似乎也是现在的品味问题.坚持像http://developer.mozilla.comhttp://caniuse.com这样的优质资源,你会很好的.

  • 浏览器"制造商"很难保持他们的浏览器标准兼容,更不用说高性能.本机实现中的大多数性能提升都是由于硬件速度更快."本土实施将迎头赶上"的借口已存在多年.年=互联网上的永恒.**如果**本机实现赶上,库将更新以使用它们.这对开源来说很酷.如果应用程序开发人员没有更新到最新的库,他们的应用程序不会突然减速,它只是不会加速. (4认同)
  • ...但是如果你向他们询问"Array.from"他们可能甚至都不知道应该做什么.JS"实用腰带"似乎过于关注推广他们那些和蔼可亲的解决方案,他们往往会忘记这样做,实际上它们正在稀释标准化过程.不需要功能就不会给浏览器"制造商"带来压力.有趣的事实:4种主流浏览器中有2种基于开源项目([1](http://www.chromium.org/),[2](https://developer.mozilla.org/en-US/文档/ Mozilla浏览器/ Developer_guide/Source_Code /水银)). (2认同)

Dav*_*sco 16

我同意这里所说的大部分内容,但我只想指出支持underscore.js的论证:库的大小.

特别是在您开发打算主要在移动设备上使用的应用程序或网站时,生成的捆绑包的大小以及对启动或下载时间的影响可能起着重要作用.

为了比较,这些尺寸是我在运行离子发射后使用source-map-explorer注意到的尺寸:

lodash: 523kB
underscore.js: 51.6kb
Run Code Online (Sandbox Code Playgroud)

  • 2018年3月 - lodash.min.js为72,5 kB,而underscore-min.js为16,4 kB (5认同)
  • 我想知道你从哪里得到 523kB 的?https://lodash.com/ 说它只有 24kB 压缩。下载的只有 74kB (2认同)

qbo*_*lec 10

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

如果有人发布了一篇包含这些差异的完整列表的文章,我将非常感激.让我先从我学到的东西开始(也就是让我的代码在生产中爆炸的东西:/):

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

  • 在lodash中,链接传递一个惰性迭代器,并且需要和端点像`_(something).map(foo).value()`. (3认同)

pil*_*lau 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%代码覆盖率


Cra*_*ker 6

我刚发现一个差异最终对我很重要.lodash的的非下划线兼容的版本_.extend()没有在类级别定义的属性或方法复制.

我在CoffeeScript中创建了一个Jasmine测试来演示:

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

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