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:
- Underscore.js has inconsistent support for arrays, strings, objects, and
arguments
objects. In newer browsers, Underscore.js methods ignore holes in arrays, "Objects" methods iteratearguments
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 returningfalse
- 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 parameterundefined
is Lodash_.indexOf
- Underscore.js
_.indexOf
with third parametertrue
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 aniteratee
is Lodash_.uniqBy
- Underscore
_.where
is Lodash_.filter
- Underscore
_.isFinite
doesn’t align withNumber.isFinite
(e.g._.isFinite('1')
returnstrue
in Underscore.js, butfalse
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 areMap
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)