根据MDN,提供给forEach
函数的回调被赋予了3个参数:currentValue
,index
,array
。
我试图理解forEach
回调的目的是将array
本身的引用作为第三个参数,我能明白为什么的唯一原因是因为范围。
第一个例子:
function printLastName(value, index, array) {
if (index === (array.length - 1)) {
console.log(value);
}
}
function setupNames() {
const names = ['A', 'B', 'C'];
names.forEach(printLastName);
}
setupNames();
我想在上面的第 1 个示例中说明的是,用作forEach()
回调的printLastName()
没有对原始names
数组的引用,因此,如果它需要使用数组,则需要提供3rd parameter
,因此我明白为什么forEach
回调提供对原始array
的引用的唯一原因。
第二个例子:
function setupNames() {
const names = ['A', 'B', 'C'];
names.forEach((value, index, array) => {
if (index === (names.length - 1)) {
console.log(value);
}
});
}
setupNames();
在第二个示例中,行(index === (names.length - 1))
,我可以使用names
或array
,因为它可供我使用。据我了解,使用任何一个绝对没有区别。
总结一下,这是我的问题:
forEach
方法的callback
仅因为范围问题(第一个示例(而不是出于任何其他原因而将array
作为3rd parameter
提供,对吗?- 在第二个示例中,无论lambda回调逻辑是什么,我在lambda回调中使用
names
或array
forEach
绝对没有区别,对吗?
我最近遇到了这个用例,这让我明白了为什么数组参数很有用(当我以前也没有看到它的用处时(。
考虑:
const names = ['John', 'Paul', 'John Paul', 'John Smith', 'James'];
names.filter(n => n.startsWith('John')).forEach((john, index, array) => {
// If it's not the first or last entry, then we want to write it to console
if (index !== 0 || index !== array.length - 1) console.log(john);
});
如果您由于.filter
等原因创建新集合,则如果按上述方式编写,则新集合将不可用作参考。数组参数允许您访问正在使用的集合.forEach
。
所有特性都来自规范和提案,所以进入 ECMAScript 规范。
它似乎没有一个非常具体的理由存在。但正如您所说,在分析可能使用forEach
的不同示例时,这是由于范围界定是有道理的。例如,当定义泛型函数时,例如:
function calculateSomethingThatNeedsLookupInTheArray(val, index, array
.如果我们只依赖上下文,如果我们只引用使用此函数的数组,那么在实现中会更加严格。
const array1 = [1 , 2, 3, 4, 5]
const array2 = [1, 2]
array1.forEach((val) => {
something(val / array1[0]))
array2.forEach((val) => {
something(val, array2[0]))
与
const array1 = [1 , 2, 3, 4, 5]
const array2 = [1, 2]
const operationCallback = (val, i, array) => {
something(val /array[0])
}
array1.forEach(operationCallback)
array2.forEach(operationCallback)
还要记住,除了回调之外,我们可以将任何上下文传递给forEach,称为thisArgument
,这突出了保持数组的范围或目标我们正在使用的当前数组的重要性。