只是想分享一个我学会的将变量传递到 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);
无法从循环内访问数据集。那么我们如何在迭代时访问它呢?
我还没有在堆栈溢出上看到这个解决方案,它不适合我能找到的任何问题。
答案如下:
最佳答案
如果您的函数超出了某些数据的范围,但需要访问它,您可以使用柯里化(Currying)函数,该函数将该数据集作为第一个参数,并且仍然可以在整个过程中正常使用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))
关于javascript - 如何将额外的参数传递给 JS Array.forEach(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58940240/