Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does forEach() bind by reference?

var arr = ['Foo'];

arr.forEach(function(item){
  console.log(item);
  item = 'Lorem';
  console.dir(arr[0]);

});

for (var item in arr){
  arr[item] = 'Ipsum';
  console.dir(arr[0]);
}

Like the code above shows, I noticed that changing the value of an item passed to the callback of forEach() does not cause the iterated object to alter.

Using for...in certainly does.

Why is that & how should I alter values in an array?

I find that the topic is covered quite confusing on MDN

like image 355
Wottensprels Avatar asked May 30 '14 22:05

Wottensprels


People also ask

Does forEach run sequentially?

Foreach is guaranteed to be sequential for sequential collections (that is, the normal hierarchy, or for anything transformed by .

Is forEach a callback function?

The forEach() method calls a specified callback function once for every element it iterates over inside an array. Just like other array iterators such as map and filter , the callback function can take in three parameters: The current element: This is the item in the array which is currently being iterated over.

Does forEach run synchronously?

Note: forEach expects a synchronous function. forEach does not wait for promises. Make sure you are aware of the implications while using promises (or async functions) as forEach callback.

What is the function of forEach ()?

The forEach() method calls a function for each element in an array. The forEach() method is not executed for empty elements.


2 Answers

Using for...in certainly does.

No it doesn't. Your forEach loop is equivalent to this for...in loop (apart from the order):

for (var index in arr) {
  var item = arr[index];
  console.log(item);
  item = 'Lorem';
  console.dir(arr[0]);
}

Do you see that the array isn't modified either? That's because JavaScript is always pass-by-value, and there is a very simple rule to keep in mind:

Assigning a value to a variable never changes the value of another variable or data structure.

That means, assigning a new value to item, cannot change an element of arr. If you want to to modify the array, you have to mutate it directly by assigning a value to an index, i.e.

arr[index] = 'foo';
like image 64
Felix Kling Avatar answered Oct 03 '22 00:10

Felix Kling


In your case, the item variable is passed by value, because it is of a primitive value. If it were a json object, and you would change one of its properties, it would be reflected on the original list.

In this situation, you can use other arguments that the forEach has. For example:

arr.forEach(element, index, array) {
    ...
}

Using these arguments, you can affect directly array[index]

like image 27
tigermarques Avatar answered Oct 03 '22 00:10

tigermarques