Reputation: 3149
I learned that a for
iterates on each the array's element, even if a pointed case doesn't exist, while a forEach
skips the unexisting cases.
Moreover, when a for
is writen, a counter must be specified (I'm not speaking about for...in
), while a forEach
just uses a function iterator.
Well. Could you answer to the four following questions please ?
forEach
skips unexisting arrays' cases while a for
doesn't ?forEach
uses an intern counter (we just don't have to write it) ? Or is it a totally different mechanism than a for
?forEach
doesn't go through an array in the same order than the array's order. What about JavaScript Upvotes: 3
Views: 2271
Reputation: 875
The for
keyword is a language construct, this is the fastest and most "raw" way to iterate over things. It has three styles:
The C-style for
: for ( initializer; condition; iterator ) { code... }
- this one is the most flexible and time-tested version. To iterate over a list, you start going over all list indexes from 0 to the list's length. You can also
go over every other, third etc element. Most of the time, this is good enough.
The Javascript for-in
for (var key in object) { code ... }
- this one is a good way to go over every key in an object, for example, to output all values of a JSON object.
(ES2015) The Javascript for-of
: for (var item of collection) { code ... }
- this one is new and available in modern browsers. It lets you skip the indexes and counters, and lets you walk over every item of a collection. (Say, every object in a products list.) It does the same thing as the C-style for, but is easier to use.
However, the forEach
function is specific to Array
objects in Javascript, and lets you run a function for every item in an array. It's good if you have an utility function that does all the work for you.
Here's how to use all of the above kinds of iteration:
// most plain kind of array with a length of 7
var myArray = [1, 2, 3, 4, 5, 6, undefined];
// a weird kind of array with no values between index 3 and 100
// its length is 102
var mySparseArray = [1, 2, 3, 4];
mySparseArray[100] = 5;
mySparseArray[101] = 6;
// 1. C-style for
// ** can control how index is incremented
// ** needs an extra variable to iterate with
for (var i = 0; i < myArray.length; i += 1) {
console.log(myArray[i]);
// logs 1, 2, 3, 4, 5, 6, undefined
}
for (var i = 0; i < mySparseArray.length; i += 1) {
console.log(myArray[i]);
// logs 1, 2, 3, 4, undefined, undefined, ... (up to index 100), 5, 6
}
// 2. for..in
// ** keys are iterated over in non-guaranteed order
// (you might get 2, "length", 1, 0, 3)
// ** all enumerable keys are included, that might include things other than indexes.
for (var key in myArray) {
console.log(myArray[key]);
// logs 1, 2, 3, 4, 5, 6
}
for (var key in mySparseArray) {
console.log(mySparseArray[key]);
// logs 1, 2, 3, 4, 5, 6
// this for-loop "thinks" the array is an object with numbers for keys
}
// 3. for..of
// ** only available in browsers with ES2015 support
// ** supports many other things than Arrays - TypedArrays, Iterators...
for (var item of myArray) {
console.log(item);
}
for (var item of mySparseArray) {
console.log(item);
// logs 1, 2, 3, 4, undefined, undefined, ... (up to index 100), 5, 6
}
// 4. forEach
// ** calls a function for each element (considered slow)
// ** supports only Arrays (unless you call it with Array.prototype.forEach.call)
function myCallback(element) {
console.log(element);
}
myArray.forEach(myCallback); // logs 1, 2, 3, 4, 5, 6
mySparseArray.forEach(myCallback); // logs 1, 2, 3, 4, 5, 6
Make sure to try these out in your browser's developer console! You can see each of the above pieces of code in action.
Make sure to check out the MDN reference on iterations.
Upvotes: 3
Reputation: 31181
vlaz has already answered in comments, I would just had:
The main difference is that the forEach
call can generate one closure by element in the array, which is very useful when you need to reuse some internal variables.
Upvotes: 1
Reputation: 29028
So, when you're talking about a for
loop you mean an actual for
loop, not for...in
(which should not be used on arrays). There seems to be a slight misconception and let me start off with that:
A for
loop is not meant to loop over arrays. Not that you shouldn't or it's bad but that's not it's primary function - it literally just loops until a condition is met then it stops. The most common syntax happens to be for (var i =0; i < max; i++)
which happens to match well for array looping but that doesn't mean that you can't have, say, for (var i = 100; Number.isInteger(i); i = i/2)
. So, with that said, here are answers to your questions:
forEach
skip missing items in the array?forEach
is an array method and along with map
, reduce
and others it does skip unassigned slots. This is to aid in working with sparse arrays, for example
var arr = [];
arr[5] = "five";
arr[7] = "seven";
arr[10] = "ten";
console.log("---using forEach---");
arr.forEach(function(item) {
console.log(item);
});
console.log("---using a for-loop---");
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
This is a simple example that illustrates why you might want to use the sparse array loop - as you can see, you get way less code executions. Here is a slightly more elaborate one:
var arr = [];
arr[5] = "five";
arr[42] = "the answer";
arr[9001] = "over nine thousand";
arr.forEach(function(item) {
console.log(item);
});
A straight for
loop will have executed (literally) over nine thousand times, when all you have is three items.
I have to clarify something here - unset values are any indeces you have not assigned anything to. Assigning undefined
does count as assigning still:
var arr = [];
arr[5] = "five";
arr[7] = undefined;
arr[10] = "ten";
arr.forEach(function(item) {
console.log(item);
});
forEach
use an internal counterYou can get a hold of the current result easily, since it's passed into the callback.
var arr = [];
arr[5] = "five";
arr[42] = "the answer";
arr[9001] = "over nine thousand";
arr.forEach(function(item, index) {
console.log(index, "-", item);
});
forEach
go inThe above should show you that. Here is another quick example:
var alphabet = ["a", "b", "c", "d", "e", "f", "g" ];
alphabet.forEach(function(letter, index) {
console.log(index, letter);
})
for
and forEach
The differences between the two are what I alluded to in the beginning - for
is a generic loop operator in JavaScript - you can use it to go through arrays but you can use it for various other purposes, too. forEach
, by contrast, is specifically bound to arrays. It's very hard to compare the two realistically but if we restrict to only talking about using them on arrays, here are some points
for
break
or return
, so you don't need to loop over the entire arrayfor (var i = arr.length; i >= 0; i--)
) or perhaps even go back or skip items (doing i--
or i += 2
inside the loop body)forEach
.forEach
calllet
and const
that matters less)find
.for...of
Thanks to @Bergi, I remembered something that I did want to include here:
One loop you didn't mention but exists is the for...of
loop which is similar in syntax to the for...in
loop but it is designed to work on arrays as well as other iterable objects. It is a relatively new construct (newer than forEach
at least) as it is in the ES6 specifications, so wide web-support might not be there but it is an alternative to both of the above. It is pretty simple to use:
var arr = [];
arr[5] = "five";
arr[7] = "seven";
arr[10] = "ten";
for (item of arr) {
console.log(item);
}
So, in short, it works like a for
loop since it goes over everything, but you don't have to declare and maintain a counter.
Upvotes: 3