Using _.each cleans up your javascript loops
Native for:
for (var i = 0; i < posts.length; i++) {
var post = posts[i];
for (var j = 0; j < post.comments.length; j++) {
var comment = comments[j];
console.log(comment.body);
}
};
Native forEach (Modern Browsers)
posts.forEach(function(post) {
post.comments.forEach(function(comment) {
console.log(comment.body);
});
});
Underscore each (Cross-Browser):
_.each(posts, function(post) {
_.each(post.comments, function(comment){
console.log(comment.body);
});
});
** Suger each (Cross-Browser) **
http://sugarjs.com/api/Array/each
posts.each(function(post) {
post.comments.each(function(comment){
console.log(comment.body);
});
});
I know the native for loops are more efficient but for me clean readable code takes precedence.
[Edit] Additionally there is the ECMAScript 5's native forEach method which _.each delegates to but it's not supported by IE8. I'm a huge fan of the underscore.js library so I still prefer using the cross-browser _.each method.
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach
If you want to avoid using underscore.js you can conditionally patch older browsers to support forEach with the following (taken from the link above):
if ( !Array.prototype.forEach ) {
Array.prototype.forEach = function(fn, scope) {
for(var i = 0, len = this.length; i < len; ++i) {
fn.call(scope || this, this[i], i, this);
}
}
}
Written by Tim Santeford
Related protips
6 Responses
Good read. But everyone should be aware, extending Array's prototype chain breaks the way Javascript enumerates over Arrays with for
loops.
I wouldn't recommend this.
Firstly, you need to load a 3rd party script to get the _.each()
method.</p>
Secondly, that's not the proper way to extend native objects. It's not future proof. You should check for existence of each
and if not found use Object.defineProperty
to define a new property,</p>
Thirdly, there is no mention of the native forEach
method. Underscore actually delegates to that if it exists.</p>
I agree, I don't see the reason to extend Array.protype, when wrapped code can be very readable as well. Besides, using underscore methods looks really sweet, when coding in Coffeescript:
_.each items, (item)-> item.doSomeStuff()
@paprikkastudio even sweeter without underscore:
item.doSomeStuff() for item in items
@greelgorke Of course! How could I forget that:D
Also, don't forget underscore's higher level methods. For instance, if you just want to call a method on each item, it'd be clearer to do: _.invoke(items, 'doSomeStuff'). Can use _.pluck to get a property off of a collection, etc.