lodash和下划线之间的差异

时间:2012-12-09 17:08:36

标签: underscore.js javascript lodash

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

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

我认为两者都很精彩,但我对他们如何进行有根据的比较工作知之甚少,我想更多地了解这些差异。

12 个答案:

答案 0 :(得分:1925)

我创建了Lo-Dash,为数组,字符串,对象和arguments对象 1 提供更一致的跨环境迭代支持。它已成为Underscore的超集,提供更一致的API行为,更多features(如AMD支持,深度克隆和深度合并),更彻底的documentation和单元测试(在Node中运行的测试) ,Ringo,Rhino,Narwhal,PhantomJS和浏览器),更好的整体性能和大型数组/对象迭代的优化,以及custom builds和模板预编译实用程序的更大灵活性。

由于Lo-Dash比Underscore更新频率更高,因此lodash underscore版本is provided可以确保与最新稳定版本的Underscore兼容。

有一次我甚至给了Underscore push access,部分原因是因为Lo-Dash负责筹集超过30个问题;登陆错误修复,新功能,&在Underscore v1.4.x +中获得性能提升。

此外,默认情况下至少有3个Backbone样板包含Lo-Dash,现在Backbone的官方documentation中提到了Lo-Dash。

查看Kit Cambridge的帖子Say "Hello" to Lo-Dash,了解Lo-Dash和Underscore之间差异的更深层细分。

脚注:

  1. Underscore对数组,字符串,对象和arguments对象的支持不一致。在较新的浏览器中,Underscore方法忽略holes in arrays,“Objects”方法迭代arguments个对象,字符串被视为类似数组,方法正确迭代函数(忽略它们的“原型”属性)和对象(迭代)阴影属性,如“toString”和“valueOf”),而在较旧的浏览器中,它们不会。此外,像_.clone这样的Underscore方法会保留数组中的漏洞,而像_.flatten这样的其他方法则不会。{/ li>

答案 1 :(得分:179)

Lo-Dash的灵感来自下划线,但现在是卓越的解决方案。您可以设置custom builds,拥有higher performance,支持AMD并拥有great extra features。在jsperf和.. Lo-Dash vs Underscore benchmarks上查看awesome post about 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 }]

(摘自lodash docs

答案 2 :(得分:73)

如果像我一样,你期待下划线和lodash之间的使用差异列表,那就是guide for migrating from underscore to lodash

以下是后人的现状:

  
      
  • 下划线_.any是Lodash _.some
  •   
  • 下划线_.all是Lodash _.every
  •   
  • 下划线_.compose是Lodash _.flowRight
  •   
  • 下划线_.contains是Lodash _.includes
  •   
  • 下划线_.each不允许退回false
  •   
  • 下划线_.findWhere是Lodash _.find
  •   
  • 默认情况下,下划线_.flatten很深,而Lodash很浅
  •   
  • 下划线_.groupBy支持传递参数(value, index, originalArray)的iteratee,   在Lodash中,_.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的{​​{1}}下划线是Lodash iteratee
  •   
  • 下划线_.uniqBy是Lodash _.where
  •   
  • 下划线_.filter_.isFinite不一致   (例如Number.isFinite在下划线中返回_.isFinite('1')但在Lodash中返回true
  •   
  • 下划线false速记不支持深度比较   (例如_.matches
  •   
  • 下划线≥1.7& Lodash _.filter(objects, { 'a': { 'b': 'c' } })语法为_.template
  •   
  • Lodash _.template(string, option)(data)缓存是_.memoize类似对象
  •   
  • 对于许多支持Map的方法,Lodash不支持context参数
  •   
  • Lodash支持implicit chaininglazy chaining, & shortcut fusion
  •   
  • Lodash将其重载_.bind_.head_.last和& _.rest进入   _.initial_.take_.takeRight,& _.drop
      (即在Lodash中,Underscore中的_.dropRight_.head(array, 2)
  •   

答案 3 :(得分:60)

除了John的回答,还读起lodash(我以前认为是“me-too”来强调),并看到性能测试,阅读源代码和blog posts,使得lodash优于下划线的几点是:

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

      

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

         

    请先阅读博客文章,而不是相信它,而是通过运行benchmarks来判断自己。我现在很震惊,看到一个lodash甚至比简单原生功能(例如Chrome中的Array.every功能)下划线快100-150%!

  2. lodash中的 extras 也很有用。

  3. 至于Xananax高度评价的评论暗示对下划线代码的贡献:拥有 GOOD 竞争总是更好,它不仅可以保持创新,还可以促使您保持自己(或您的图书馆)状态良好。
  4. 这是lodash之间的list of differences,它的下划线构建是您的下划线项目的替代品。

答案 4 :(得分:43)

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

恕我直言,这次讨论不成比例。引用前面提到的blog post

  

大多数JavaScript实用程序库,例如Underscore,Valentine和   吴,依靠“原生第一的双重方法。”这种方法更喜欢   本机实现,只有在使用时才能回归到vanilla JavaScript   不支持本机等效。但是jsPerf透露了一个有趣的内容   趋势:迭代数组或类似数组的最有效方法   集合是为了完全避免本机实现,选择   简单的循环。

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

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

也许你们都在为需要慌张表现的大型项目工作,这样你们才能真正看到差异between 850,000 (underscore) vs. 2,500,000 (lodash) iterations over a list per sec

我不是。我的意思是,我工作的项目我必须解决性能问题,但它们从未解决或由Underscore和Lo-Dash引起。除非我抓住实现和性能的真正差异(我们现在正在谈论C ++),让我们说一个循环遍及一个可迭代的(对象或数组,稀疏或不稀疏!),我宁愿不被任何困扰声称基于is already opinionated

的基准平台的结果

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

  

你的实用腰带

......下次。

所以要保持相关性:

  • 如果您在不牺牲原生能力的情况下使用Underscore,请使用Underscore。
  • 使用Lo-Dash,如果您进入方便状态并且喜欢其扩展功能目录(深层复制等),并且如果您迫切需要即时性能,最重要的是不要介意尽快安排替代方案原生API的优秀见解工作。哪个会很快发生。周期。
  • 甚至还有第三种解决方案。 DIY!了解您的环境。了解不一致。阅读他们的(John-DavidJeremy)代码。如果不能解释为什么真正需要一致性/兼容性层并且增强您的工作流程或提高应用程序的性能,请不要使用这个或那个。很可能您的要求满足于您完全能够自己编写的简单的填充物。这两个图书馆都是普通的香草,带有一点点糖。 They both just fight over who's serving the sweetest pie。但相信我,最后两人都只是用水做饭。没有香草神,所以不可能没有香草教皇,对吗?

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

答案 5 :(得分:16)

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

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

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

lodash: 523kB
underscore.js: 51.6kb

答案 6 :(得分:10)

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

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

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

答案 7 :(得分:8)

http://benmccormick.org/2014/11/12/underscore-vs-lodash/

最新文章比较Ben McCormick的两篇文章:

  
      
  1. Lo-Dash的API是Underscore的超集。

  2.   
  3. 引擎盖[Lo-Dash]已完全重写。

  4.   
  5. Lo-Dash肯定不比Underscore慢。

  6.   
  7. Lo-Dash添加了什么?

         
        
    • 可用性改进
    •   
    • 额外功能
    •   
    • 表现增益
    •   
    • 链接的简写语法
    •   
    • 自定义构建仅使用您需要的内容
    •   
    • 语义版本控制和100%代码覆盖率
    •   
  8.   

答案 8 :(得分:6)

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

我在CoffeeScript中创建了一个Jasmine测试,用于演示:

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

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

答案 9 :(得分:3)

lodash 已获得_.mapValues(),与低估的_.mapObject()相同。

答案 10 :(得分:0)

在大多数情况下,下划线是lodash的子集。有时,像目前的下划线将有很酷的小函数lodash没有像mapObject。这个为我的项目开发节省了很多时间。

答案 11 :(得分:-1)

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

它们都是实用程序库,它利用JavaScript的实用程序领域...

似乎 Lodash 现在正在定期更新,因此更多地用于最新项目...

Lodash 似乎也减轻了几个KB ...

两者都有一个不错的api和文档,但是我认为 Lodash 会更好...

以下是每个文档的屏幕快照,用于获取数组的第一个值...

下划线:

underscore

破折号: lodash

由于情况可能会不时更新,因此也请检查其网站...

lodash

underscore