The difference between `_.forEach` and `$.each`
Solution 1
_.forEach
and $.each
differs for the arguments passed to the callback.
If you use _.forEach
, the first argument passed to the callback is the value, not the key.
So if you don't bother at all about the key you should use _.forEach
.
Other differences:
-
_.forEach
it will be a bit faster as it uses the nativeArrray.prototype.forEach
in modern browsers. - the this value is also different. jQuery's behavior doesn't follow the standard, underscore's does.
Solution 2
Both of them mainly provide a replacement for the forEach function that isn't available in IE8.
They don't add much if you're iterating over arrays.
The main difference, apart the order of the callback arguments, is that in jQuery the value is also available as context of the callback's call (this is why the value, less important, is only the second argument provided). This isn't really a major reason to prefer it unless you really like to avoid passing an argument to the function :
var product = 1;
$.each([1, 2, 3], function(){ product *= this });
Most often, you don't use both libraries, so you simply use the iterating function provided by the library you have.
If you happen to import both libraries, I would suggest to use the underscore function as
- it's the most similar to the standard ECMAScript function on arrays so you'll more easily migrate the day IE8 will be dead
- it's more efficient as it uses the native function when it's available :
...
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
...
Solution 3
jQuery looks like:
something.each( function(index, Element) )
Underscore looks like:
_.each(list, function(Element, index, list), [context])
// or
_(list).each(function(Element, index, list), [context])
Native array.forEach looks like:
array.forEach(function(Element, index, list), [context])
So:
- Underscore keeps the same argument order as native
forEach
- There are two differences between JQuery's and Underscore's implementation:
- JQuery sets
this
toElement
, native and Underscore allow you to provide your own context - Native and underscore also provide the list itself as third argument to the callback.
- JQuery sets
Edit: Why is it useful to be able to set the context?
Consider that you have some kind of object:
var worker = new FooWorker();
worker.process(something);
worker.process(somethingElse);
Say you want to call that method on every value from an array.
Using the context parameter, you can simply say:
myArray.forEach(worker.process, worker);
while without it you'd need to be more verbose (and do one more function call per element):
// native
myArray.forEach( function(i, e) {worker.process(e);} );
// jquery
$(myArray).each( function() {worker.process(this); } );
This is one situation where JQuery's foreaching convention makes things less convenient.
Related videos on Youtube
Lorraine Bernard
Updated on June 25, 2022Comments
-
Lorraine Bernard almost 2 years
These two functions,
_.forEach
and$.each
, taken respectively fromunderscore
andjQuery
seems to make the same thing.What are the possible reasons to prefer one implementation to the other?
-
Christoph over 11 yearsi would not make my decision which framework to take dependent on a single method...
-
Kos over 11 yearsUnderscore isn't a framework
-
I Hate Lazy over 11 yearsUse the underscore version. It follows the standard.
-
-
Moritz Roessler over 11 yearsJquery doesn't use the native foreach if available? Thx, I didn't knew that
-
I Hate Lazy over 11 yearsThe
this
value is also different. jQuery's behavior doesn't follow the standard, underscore's does. And underscore lets you set thethis
value with a third argument. -
I Hate Lazy over 11 yearsunderscore also accepts a plain object instead of an Array. jsfiddle.net/zdF6D jQuery's feature set is less complete, because it doesn't let you set the
this
value of the callback via a 3rd argument. -
Denys Séguret over 11 years@IHateLazy You're right. I had read the source too fast...
-
I Hate Lazy over 11 yearsI really wish jQuery had its parameters switched around. I can live without being able to set the
this
value of the callback, but the flipped params drives me a little crazy. -
Denys Séguret over 11 yearsThis is, in fact, confusing. I agree to that. And the fact that you can't always use this because it may be boxed forbids you to simply always use this.