Reputation: 3284
Underscore.js has two ways of calling functions, which I will refer to as object-style and function-style. Object-style looks like the following:
_(myObject).each(function (val, key) {
console.log(key, val);
});
Function-style, on the other hand, looks like this:
_.each(myObject, function (val, key) {
console.log(key, val);
});
I was happily using object-style calls in my code, but at some point, however, the object style of call disappeared from the underscore.js documentation (though object-style calls still work perfectly fine). I've also seen hints around the place (like in the backbone.js documentation) that the function-style is 'better' or 'preferred'.
So, is the function-style of call the preferred method? And if so, can someone explain the reasoning behind this?
Update: @ggozad has partially answered my question. But it seems my understanding of how underscore.js works was formed way back around version 0.4.2. Reading through the change history for underscore.js, you can see this entry for version 1.2.4:
You now can (and probably should) write
_.chain(list)
instead of_(list).chain()
.
I would like to know why you should write _.chain(list)
instead of _(list).chain()
.
Upvotes: 25
Views: 12670
Reputation: 8528
The answer by @ggozad is actually very misleading. The object-oriented style has nothing to do with chaining. The example given:
_([1,2,3]).map(function (item) { return item * 2; }).map(function (item) { return item*3;});
is actually not using underscore chaining at all! It only works because the built-in JS array object has it's own map() function. Try a function that's not built-in (like shuffle) and you'll see it breaks:
_([1,2,3]).shuffle().shuffle();
The only way to get underscore chaining is to call chain()
, which you can do using either style (OO or functional).
As for why the documentation says you should use _.chain
, I'm guessing it's just a style preference. I've opened an issue at GitHub for clarification.
Upvotes: 32
Reputation: 13105
When _
is used as a function it essentially wraps the argument. The wrapper provides all the normal underscore functions.
The difference it makes apart from style is that using the OOP style (or object style in your definition) is that it produces chainable wrapped objects. So it's easy to do:
_([1,2,3]).map(function (item) { return item * 2; }).map(function (item) { return item*3;});
The equivalent would be:
_.map(_.map([1,2,3], function (item) { return item * 2 }), function (item) { return item * 3 });
which is probably less clear.
Upvotes: 0