关于underline.js: lodash and underscore 之间的区别

Differences between lodash and underscore

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

罗达什似乎是一个替代下划线的下降,后者已经存在了更长的时间。

我认为两者都很出色,但我不太了解它们是如何工作的,无法进行有教育意义的比较,我想了解更多的差异。


我创建了lo dash来为数组、字符串、对象和arguments对象提供更一致的跨环境迭代支持1。它已经成为下划线的超集,提供了更一致的API行为、更多的功能(如AMD支持、Deep Clone和Deep Merge)、更全面的文档和单元测试(在节点、Ringo、Rhino、Narwhal、Phantomjs和浏览器中运行的测试)、更好的总体性能和大型数组/对象迭代的优化,以及更灵活的定制构建和模板预编译实用程序。

由于lo dash的更新频率高于下划线,因此提供了lodash underscore构建,以确保与下划线的最新稳定版本兼容。

在某一点上,我甚至可以通过推送访问下划线,部分原因是LoDash负责引发30多个问题:登录错误修复、新功能以及下划线v1.4.x+的性能提升。

此外,至少有3个主干样板文件默认包括lo dash,而lo dash现在已在主干文件中提到。

查看KitCambridge的帖子,从"你好"到"低破折号",深入分析"低破折号"和下划线之间的区别。

脚注:

  • 下划线对数组、字符串、对象和arguments对象的支持不一致。在较新的浏览器中,下划线方法忽略数组中的孔,"对象"方法迭代arguments对象,字符串被视为类似数组,方法正确迭代函数(忽略其"原型"属性)和对象(迭代隐藏的属性,如"toString"和"valueof"),而在较旧的浏览器中,它们不会。此外,强调像_.clone这样的方法保留了数组中的孔,而像_.flatten这样的方法则没有。

  • 低破折号的灵感来源于下划线,但现在是更好的解决方案。你可以做你的定制版本,有更高的性能,支持AMD和有伟大的额外功能。检查此长划线与JSPERF和..上的下划线基准。这篇关于Lo Dash的精彩文章:

    使用集合时最有用的功能之一是速记语法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    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之间的用法差异列表,那么这里有一个从下划线迁移到lodash的指南。

    以下是子孙后代的现状:

    • Underscore _.any is Lodash _.some
    • Underscore _.all is Lodash _.every
    • Underscore _.compose is Lodash _.flowRight
    • Underscore _.contains is Lodash _.includes
    • Underscore _.each doesn’t allow exiting by returning false
    • Underscore _.findWhere is Lodash _.find
    • Underscore _.flatten is deep by default while Lodash is shallow
    • Underscore _.groupBy supports an iteratee that is passed the parameters (value, index, originalArray),
      while in Lodash, the iteratee for _.groupBy is only passed a single parameter: (value).
    • Underscore _.indexOf with 3rd parameter undefined is Lodash _.indexOf
    • Underscore _.indexOf with 3rd parameter true is Lodash _.sortedIndexOf
    • Underscore _.indexBy is Lodash _.keyBy
    • Underscore _.invoke is Lodash _.invokeMap
    • Underscore _.mapObject is Lodash _.mapValues
    • Underscore _.max combines Lodash _.max & _.maxBy
    • Underscore _.min combines Lodash _.min & _.minBy
    • Underscore _.sample combines Lodash _.sample & _.sampleSize
    • Underscore _.object combines Lodash _.fromPairs and _.zipObject
    • Underscore _.omit by a predicate is Lodash _.omitBy
    • Underscore _.pairs is Lodash _.toPairs
    • Underscore _.pick by a predicate is Lodash _.pickBy
    • Underscore _.pluck is Lodash _.map
    • Underscore _.sortedIndex combines Lodash _.sortedIndex & _.sortedIndexOf
    • Underscore _.uniq by an iteratee is Lodash _.uniqBy
    • Underscore _.where is Lodash _.filter
    • Underscore _.isFinite doesn’t align with Number.isFinite
      (e.g. _.isFinite('1') returns true in Underscore but false in Lodash)
    • Underscore _.matches shorthand doesn’t support deep comparisons
      (e.g. _.filter(objects, { 'a': { 'b': 'c' } }))
    • Underscore ≥ 1.7 & Lodash _.template syntax is_.template(string, option)(data)
    • Lodash _.memoize caches are Map like objects
    • Lodash doesn’t support a context argument for many methods in favor of _.bind
    • Lodash supports implicit chaining, lazy chaining, & shortcut fusion
    • Lodash split its overloaded _.head, _.last, _.rest, & _.initial out into
      _.take, _.takeRight, _.drop, & _.dropRight
      (i.e. _.head(array, 2) in Underscore is _.take(array, 2) in Lodash)


    除了约翰的回答,以及阅读关于lodash的文章(我以前认为这是一个"我也"来强调),以及看到性能测试、阅读源代码和博客文章,使lodash远远优于强调的几点是:

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


    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 performance is 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, native functions such as Array.every in Chrome!

  • 罗达什的额外费用也很有用。

  • 至于xananax的高度乐观的评论,它建议对强调的准则作出贡献:拥有良好的竞争总是更好的,它不仅能保持创新,而且能促使你保持良好的状态(或你的图书馆)。
  • 这里列出了lodash之间的区别,它的下划线构建是对下划线项目的替换。


    现在是2014年,晚了几年。但我认为我的观点是:

    我觉得这个讨论有点不合时宜。引用上述博客文章:

    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"比数组或对象方法实现更为原生。哎呀…

    有一个单一的真理来源当然很好,但是没有。即使你被告知没有,也没有香草神,亲爱的。我很抱歉。唯一的假设是,我们都在编写旨在在所有主要浏览器中表现良好的JavaScript代码,因为我们知道所有浏览器都具有相同事物的不同实现。委婉地说,这是一个需要应付的婊子。但这是前提,不管你喜欢与否。

    也许你们都在研究需要Twitter性能的大型项目,这样你们就可以真正看到每秒列表中850000次(下划线)和2500000次(lodash)迭代之间的差异了!

    我一个人不是。我的意思是,我工作的项目必须解决性能问题,但它们从来没有得到解决,也不是由下划线或长划线造成的。除非我了解在执行和性能上的真正差异(我们现在谈论C++),让我们说一个循环在一个迭代(对象或数组,稀疏或不!)上。我宁愿不为任何基于基准平台结果的声明而烦恼,因为基准平台已经是固执己见的。

    它只需要对Lets-Say Rhino进行一次单一的更新,就可以让它的数组方法实现以一种没有任何一个"中世纪的循环方法能够永远更好地执行,什么都不能"的方式启动,牧师可以围绕着这样一个简单的事实争论,即FF中所有突然出现的数组方法都比他/她的自以为是的大脑快得多。伙计,你不能通过欺骗你的运行环境来欺骗你的运行环境!提升的时候考虑一下…

    your utility belt

    …下一次。

    因此,为了保持相关性:

    • 如果在不牺牲本地ish的情况下方便使用,请使用下划线。
    • 如果您很方便并且喜欢它的扩展功能目录(深度复制等),并且如果您迫切需要即时性能,最重要的是,不要介意在本机API的高瞻远瞩的工作成果出现时就选择一种替代方案。这很快就会发生。时期。
    • 甚至还有第三种解决方案。自己动手做!了解你的环境。了解不一致。阅读他们的(约翰·大卫和杰里米的)密码。如果不能解释为什么真正需要一致性/兼容性层,并增强您的工作流程或提高应用程序的性能,请不要使用这个或那个。很可能你的需求是满足于一个简单的polyfill,你完全能够写自己。两个图书馆都是纯香草加一点糖。他们都在为谁提供最甜的馅饼而争吵。但相信我,最终两人都只是用水做饭。没有香草神,所以就没有香草教皇,对吧?

    选择最适合您需要的方法。像往常一样。我更喜欢在实际的实现上回退,而不是在任何时候固执己见的运行时欺骗,但即使是现在看来,这似乎是一个品味问题。坚持使用优质资源,如http://developer.mozilla.com和http://canius.com,你会很好的。


    我同意这里所说的大部分内容,但我只想指出一个支持underline.js的论点:库的大小。

    特别是在您开发的应用程序或网站打算主要在移动设备上使用的情况下,产生的捆绑包的大小以及对引导或下载时间的影响可能具有重要作用。

    为了进行比较,这些大小是我在运行离子服务器之后通过源地图浏览器注意到的大小:

    1
    2
    lodash: 523kB
    underscore.js: 51.6kb


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

    如果有人发表了一篇文章列出了这些差异,我会非常感激。让我从我学到的困难的东西开始(也就是说,使我的代码在生产中爆炸的东西:/):

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


    http://benmcormick.org/2014/11/12/underline-vs-lodash/

    本·麦考密克最新的一篇文章比较了这两者:

  • 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

  • 我只是发现了一个对我来说很重要的区别。Lodash的_.extend()的非下划线兼容版本不会复制类级定义的属性或方法。

    我在CoffeeDescript中创建了一个茉莉花测试,演示了这一点:

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

    幸运的是,lodash.underscore.js保留了强调复制所有东西的行为,在我看来,这是理想的行为。


    罗达什得到了与underescore的_.mapObject()相同的_.mapValues()


    在大多数情况下,下划线是lodash的子集。有时,像现在这样,下划线会有一些很酷的小功能,lodash没有like mapobject。这一个在我的项目开发中节省了我很多时间。


    它们很相似,由洛达什接管…

    它们都是一个实用程序库,在javascript中采用了实用程序的世界…

    似乎罗达什现在更新得更频繁了,所以更多的应用在最新的项目中…

    另外,洛达什似乎是更轻的几Kbs…

    两者都有很好的API和Doc,但我认为Lodash一个更好…

    以下是获取数组第一个值的每个文档的屏幕截图…

    强调:

    underscore

    拉达什:lodash

    因为事情可能会得到及时更新,只要检查他们的网站也…

    落叶

    强调