如何将额外的参数传递到JS Array.forEach()中



我只是想分享我学到的一个小技巧,将变量传递到JS Array.forEach((方法的作用域中。

我遇到过一种情况,需要使用forEach循环来构建数据集。但我也需要访问当前范围中的变量(我需要能够在循环中引用this(。

这就是我所处的情况:

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);

无法从循环中访问数据集。那么,我们如何在迭代时访问它呢?

我还没有看到这个关于堆栈溢出的解决方案,它不适合我能找到的任何问题。

答案如下:

如果您有一个函数超出了某些数据的范围,但需要访问它,您可以使用一个以该数据集为第一个参数的curried函数,并且仍然可以在整个过程中正常使用this

//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#reduce而不是Array#forEach,该函数直接获取两个参数。由于.reduce无法设置this上下文,因此您可以使用Function#bind来设置:

//external function that uses `dataset` and `this` but it is not 
//in the context where the iteration happens
function external(dataset, 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);
}
return dataset;
}
//object to serve as `this` context for a function
var obj = {
green: "Green",
yellow: "Yellow",
red: "Red",
doSomething: function(items) {
var data = {
data: [],
bgColor:[],
};
return items.reduce(external.bind(this), 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))

拥有es6的能力如果您将使用箭头功能,将从中获取

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

来自MDN Web文档:

箭头函数没有自己的这个。的此值使用了封闭的词法范围;箭头功能遵循正常变量查找规则。所以在搜索这个不是在当前范围中,箭头函数最终会找到从它的封闭范围。

另一个很好的解释:https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4

解决方案是传递一个JSON对象作为this参数。

所以在我们有之前

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

现在我们有:

Array.forEach(function(){}, {_self: this, dataset: dataset}) 
// you can access _self and dataset just as if they were in scope

现在,您可以在使用匿名函数迭代时进行数据更改:(

完整示例:

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});

Array.prototype.forEach(callbackFun,?this(

您可以将dataset作为此参数传递给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);

我找到了一个简单的

如果您不需要上下文,您可以简单地使用它来传递任何您想要的内容。

response.services.forEach(function(service) {
//code
},undefined, <whatever i want to pass>);

刚刚在第二个参数中传递了一个未定义的参数,在第三个参数中,我将额外的参数传递到JS Array.forEach((

简称

[1,2,3].forEach(myCallback,未定义,'additionalFoo'(;

#ref

最新更新