Differences between Lodash and Underscore.js [closed] Differences between Lodash and Underscore.js [closed] javascript javascript

Differences between Lodash and Underscore.js [closed]


I created Lodash to provide more consistent cross-environment iteration support for arrays, strings, objects, and arguments objects1. It has since become a superset of Underscore.js, providing more consistent API behavior, more features (like AMD support, deep clone, and deep merge), more thorough documentation and unit tests (tests which run in Node.js, RingoJS, Rhino, Narwhal, PhantomJS, and browsers), better overall performance and optimizations for large arrays/object iteration, and more flexibility with custom builds and template pre-compilation utilities.

Because Lodash is updated more frequently than Underscore.js, a lodash underscore build is provided to ensure compatibility with the latest stable version of Underscore.js.

At one point I was even given push access to Underscore.js, in part because Lodash is responsible for raising more than 30 issues; landing bug fixes, new features, and performance gains in Underscore.js v1.4.x+.

In addition, there are at least three Backbone.js boilerplates that include Lodash by default and Lodash is now mentioned in Backbone.js’s official documentation.

Check out Kit Cambridge's post, Say "Hello" to Lo-Dash, for a deeper breakdown on the differences between Lodash and Underscore.js.

Footnotes:

  1. Underscore.js has inconsistent support for arrays, strings, objects, and arguments objects. In newer browsers, Underscore.js methods ignore holes in arrays, "Objects" methods iterate arguments objects, strings are treated as array-like, and methods correctly iterate functions (ignoring their "prototype" property) and objects (iterating shadowed properties like "toString" and "valueOf"), while in older browsers they will not. Also, Underscore.js methods, like _.clone, preserve holes in arrays, while others like _.flatten don't.


Lodash is inspired by Underscore.js, but nowadays it is a superior solution. You can make your custom builds, have a higher performance, support AMD and have great extra features. Check this Lodash vs. Underscore.js benchmarks on jsperf and... this awesome post about Lodash:

One of the most useful features, when you work with collections, is the shorthand syntax:
(although Underscore now also supports this syntax)

var characters = [  { 'name': 'barney', 'age': 36, 'blocked': false },  { 'name': 'fred',   'age': 40, 'blocked': true }];// Using "_.filter" callback shorthand_.filter(characters, { 'age': 36 });// Using Underscore.js_.filter(characters, function(character) { return character.age === 36; } );// → [{ 'name': 'barney', 'age': 36, 'blocked': false }]

(taken from Lodash documentation)


If, like me, you were expecting a list of usage differences between Underscore.js and Lodash, there's a guide for migrating from Underscore.js to Lodash.

Here's the current state of it for posterity:

  • 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.js _.indexOf with third parameter undefined is Lodash _.indexOf
  • Underscore.js _.indexOf with third 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.js, 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.js is _.take(array, 2) in Lodash)