How to pass extra arguments into JS Array.forEach()

foreach javascript
javascript foreach bind variable
array foreach polyfill
javascript foreach access outer variable
foreach push to array javascript
array foreach is not a function
javascript foreach object
javascript foreach outside variable

Just wanted to share a little trick I learned to pass variables into the scope of your JS Array.forEach() method.

I had a situation where I needed to use a forEach loop to build a dataset. But I needed to access variables in the current scope as well (I needed to be able to reference this in the loop).

This is the situation I was in:

var dataset = {
    data: [],
    backgroundColor:[],
};

items.forEach(function (item) {

    dataset.data.push(item.age);

    if (item.age < 2) {
        dataset.bgColor.push(this.green);
    } else if (item.age < 5) {
        dataset.bgColor.push(this.yellow);
    } else {
        dataset.bgColor.push(this.red);
    }

}, this);


this.refreshGraph(dataset);

Dataset isn't accessible from within the loop. So how do we access it while iterating?

I haven't seen this solution on stack overflow and it didn't fit any question I could find.

Answer below:

If you have a function out of scope of some data yet need to access it, you can use a curried function that takes that dataset as the first parameter and can still use this normally throughout:

//curried function that uses `dataset` and `this` but it is not 
//in the context where the iteration happens 
function makeLoopCallback(dataset) {
  return function(item) {
    dataset.data.push(item.age);

    if (item.age < 2) {
        dataset.bgColor.push(this.green);
    } else if (item.age < 5) {
        dataset.bgColor.push(this.yellow);
    } else {
        dataset.bgColor.push(this.red);
    }
  }
}

//object to serve as `this` context for a function
var obj = {
  green: "Green",
  yellow: "Yellow",
  red: "Red",
  doSomething: function(items) {
    var data = {
        data: [],
        bgColor:[],
    };
  
    items.forEach(makeLoopCallback(data), this);
  
    return data;
  }
}

//set up some dummy data
var input = [ { age: 1 }, { age: 2 }, { age: 3 }, { age: 4 }, { age: 5 }, { age: 6 } ];

//call the function
console.log(obj.doSomething(input))

Array.forEach() et al with additional parameters, When you want to pass additional parameters to the Array.forEach() callback function you currently must work with an additional (anonymous) the programmer has to pass multiple information in a Array or Object) or if all additional parameters will If you need a secure database library for node.js, check out @databases. Definition and Usage. The forEach() method calls a function once for each element in an array, in order.. Note: the function is not executed for array elements without values.

With the abilities of es6 If you'll use an Arrow Function the this will be taken from

items.forEach(item => {
// You can use this as out of the forEach scope
});

From MDN Web Docs:

An arrow function does not have its own this. The this value of the enclosing lexical scope is used; arrow functions follow the normal variable lookup rules. So while searching for this which is not present in current scope, an arrow function ends up finding the this from its enclosing scope.

Another nice explanation: https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4

How to Use forEach() to Iterate an Array in JavaScript, The first argument of forEach() is the callback function called for every item in the array. The second argument (optional) is the value of this set in� Summary: in this tutorial, you will learn how to use the JavaScript Array forEach() method to exeucte a function on every element in an array. Introduction to JavaScript Array forEach() method. Typically, when you want to execute a function on every element of an array, you use a for loop statement.

The solution is to pass a JSON object as the this argument.

so before we had:

Array.forEach(function(){}, this) 
// "this" is just an object ^^^^ just like anything else in JavaScript

Now we have:

Array.forEach(function(){}, {_self: this, dataset: dataset}) 

// you can access _self and dataset just as if they were in scope

And now you can make data changes while iterating with an anonymous function :)

Full example:

var dataset = {
    data: [],
    backgroundColor:[],
};

items.forEach(function (item) {

    dataset.data.push(item.age);

    if (item.age < 2) {
        dataset.bgColor.push(_self.green);
    } else if (item.age < 5) {
        dataset.bgColor.push(_self.yellow);
    } else {
        dataset.bgColor.push(_self.red);
    }
}, { _self: this , dataset: dataset});

JavaScript Arrays: .forEach - The Functional for of loop - DEV, The index parameter is optional. It is handy when the logic depends on the item's position in the array. const fruitEmojis = [� Parameters callback Function to execute on each element. It accepts between one and three arguments: currentValue The current element being processed in the array. index Optional The index currentValue in the array. array Optional The array forEach() was called upon. thisArg Optional Value to use as this when executing callback. Return value

Array.prototype.forEach(callbackFun, ?this)

You can pass dataset as this argument to forEach

var dataset = {
data: [],
backgroundColor:[],
};

items.forEach(function (item) {

this.dataset.data.push(item.age);

if (item.age < 2) {
    this.dataset.bgColor.push(this.tempThis.green);
} else if (item.age < 5) {
    this.dataset.bgColor.push(this.tempThis.yellow);
} else {
    this.dataset.bgColor.push(this.tempThis.red);
}

}, {tempThis:this,dataset:dataset});


this.refreshGraph(dataset);

Setting the variables in ES6 forEach() functions, How did the 'sandwich' and 'index' parameter automatically get detected and the About � Daily Tips � Learn JS Over the last few days, we looked at the new, easier ways ES6 let's us loop through arrays, nodelists, and objects. You pass a callback function into forEach() , and that callback accepts 3� array.forEach(callback) method is an efficient way to iterate over all array items. Its first argument is the callback function, which is invoked for every item in the array with 3 arguments: item, index, and the array itself. forEach() is useful to iterate over all array items, without breaking, involving simultaneously some side-effects.

Introduction To Array For Each, Follow along in index.js — you can run your code by copying it into your In the above example, we pass an ES6 arrow function as the argument to evens. forEach() accepts up to three arguments: the current element in the array upon which . but that seems like too many extra lines for such a simple operation. Passing Extra Parameters Extra Parameters, Fixed Variables, or Data. Sometimes objective or constraint functions have parameters in addition to the independent variable. The extra parameters can be data, or can represent variables that do not change during the optimization. There are three methods of passing these parameters:

JavaScript Array forEach: Executing a Function on Every Element, in this tutorial, you will learn how to use the JavaScript Array forEach method to execute a function on every element The forEach() method takes two arguments. This example shows how to pass the counter object to the forEach () method. Arrays are wonderful and a very particular type in JavaScript. There are many useful built-in properties and methods that will help you resolve any task which involves arrays. Today we are going to discuss 15 array methods every developer should know. some() every() reduce() map() flat() filter() forEach() findIndex() find() sort() concat() fill() includes() reverse() flatMap() Notice the list

The arguments object, arguments is an Array-like object accessible inside functions that contains the from zero, but it doesn't have Array 's built-in methods like forEach() or map() . You can pass as many arguments as you like to this function. JavaScript’s pass-by rules. JavaScript follows one rule when it comes to passing arguments into functions, which is to have different rules! JavaScript always uses pass-by-value, however when

Comments
  • "Dataset isn't accessible from within the loop.", Not sure what you mean, dataset should be visible within the forEach callback as it is in a higher scope, higher scoped variables are visible to lower scoped code
  • This is a great explanation. I learned about bind() and curried functions today. Very cool.
  • Very nice I like this a lot better. Gonna steal it.
  • @NoahGary if it worked for you I'll be glad if you mark my answer ...
  • this made what I was doing in my code a little easier so thank you. I upvoted for that. But I really was trying to ask a different question altogether. Passing in a variable to a function that is out of scope.
  • You aren't using this anywhere in your code even though you pass it in. Yet you reference properties that will be attached to this without going through it. dataset will only work because it's matching the one from the outer scope - var dataset. However, _self doesn't reference this._self. I'm not sure what the point of it is, however - it seems easier to use arrow functions and/or curried functions if you want to be more generic.
  • This is mentioned in the documentation and used in a lot of answers here on SO, also, you'll have to use this._self not just _self.
  • @VLAZ This is only a section of my full code and it is more just a proof of concept for others to understand. Please post your arrow function solution! I would love to see it.
  • Then you have a _self variable setup somewhere in a higher scope. The thisarg sets the execution context of the function (what this keyword will refer to) it does not introduce variables into the callback scope.
  • If someFunctionReferencewas a function that was not defined in the same scope, or lower scope, where dataset was defined then you would need the {dataset:dataset} argument at the end and then access it with this.dataset inside the function.
  • But now you don't have access to this.green, for example.
  • @VLAZ Now it's available.