在 JavaScript 中,你经常需要遍历数组集合,并为每次迭代执行回调方法。JS 开发人员通常会使用一种有用的方法来执行此操作:forEach()
方法。
forEach()
方法为它在数组内迭代的每个元素调用一次指定的回调函数。就像 map
和 filter
等其他数组迭代器一样,回调函数可以接受三个参数:
- 当前元素:这是当前正在迭代的数组中的项目
- 它的索引:这是该项目在数组中的索引位置
- 目标数组:这是正在迭代的数组
forEach
方法不像其他迭代器(如 filter
、map
和 sort
)那样返回新数组。相反,该方法返回 undefined
本身。所以它不像其他方法那样可链接。
forEach
的另一个点是你不能终止循环(使用 break
语句),或使其跳过一次迭代(使用 continue
语句)。换句话说,你无法控制它。
终止 forEach
循环的唯一方法是在回调函数中抛出异常。别担心,我们很快就会在实践中看到这一切。
如何在 JavaScript 中使用 forEach() 方法
想象一下,一群学生排队进行例行点名。班级协调员穿过队伍并喊出每个学生的名字,同时标记他们是否在场。
需要注意的是,协调员不会改变学生在行中的顺序。在完成点名后,他还将他们保持在同一条线上。他所做的就是对每个人执行一个操作(他的检查)。
在下面的示例中,记住这个场景,我们将看到如何使用 JavaScript 中的 forEach
方法来解决现实世界的问题。
JavaScript 中的 forEach()
方法示例
如何使用 forEach()
删除数组中的第一个奇数
在这个例子中,我们有一个数组,它在第一个位置有一个奇数,后面有几个偶数。但我们只希望这个数组中的数字是偶数。因此,我们将使用 forEach()
循环从数组中删除奇数:
let numbers = [3, 6, 8, 10, 12]
let odd = 3;
numbers.forEach(function(number) {
if (number === odd) {
numbers.shift() // 3 will be deleted from array
}
})
console.log(numbers);
[6, 8, 10, 12] // All even!
如何使用 forEach()
访问索引属性
在此示例中,我们将为在数组内部循环的每个学生执行 rollCall
函数。rollCall
函数只是将与每个学生相关的字符串记录到控制台。
names = ["anna", "beth", "chris", "daniel", "ethan"]
function rollCall(name, index) {
console.log(`Is the number ${index + 1} student - ${name} present? Yes!`)
;}
names.forEach((name, index) => rollCall(name, index));
/*
"Is the number 1 student - anna present? Yes!"
"Is the number 2 student - beth present? Yes!"
"Is the number 3 student - chris present? Yes!"
"Is the number 4 student - daniel present? Yes!"
"Is the number 5 student - ethan present? Yes!"
*/
在这个例子中,我们关于每个学生的唯一信息是他们的名字。然而,我们也想知道每个学生使用什么代词。换句话说,我们想要为每个学生定义一个代词属性。
所以我们将每个学生定义为一个具有两个属性的对象、名称和代词:
names = [
{name:"anna",pronoun: "she"},
{name: "beth",pronoun: "they"},
{name: "chris",pronoun: "he"},
{name: "daniel",pronoun: "he"},
{name: "ethan",pronoun: "he"}
]
function rollCall(student, index) {
console.log(`The number ${index + 1} student is ${student.name}. Is ${student.pronoun} present? Yes!`);
}
names.forEach((name, index) => rollCall(name, index));
/*
"The number 1 student is anna. Is she present? Yes!"
"The number 2 student is beth. Is they present? Yes!"
"The number 3 student is chris. Is he present? Yes!"
"The number 4 student is daniel. Is he present? Yes!"
"The number 5 student is ethan. Is he present? Yes!"
*/
我们将每个学生的点名消息记录到控制台,然后执行检查以查看学生使用的代词,最后我们将准确的代词作为字符串的一部分动态传递。
如何在 JavaScript 中使用 forEach()
将数组复制到新数组中
经过三年的学习,现在是每个学生毕业的时候了。在我们的 JavaScript 代码中,我们定义了两个数组:stillStudent
和 nowGraduated
。你可能已经猜到了,在学生毕业前,都是 stillStudent
。
然后 forEach
循环接收每个学生,并在其上调用 graduateStudent
函数。
在这个函数中,我们构造了一个具有两个属性的对象:学生的姓名以及他们毕业的位置。然后我们将新对象传递给 nowGraduated
数组。那个时候,学生已经毕业了。
此示例还演示了如何使用 forEach()
方法将数组复制到新数组中。
let stillStudent = ["anna", "beth", "chris", "daniel", "ethan"]
let nowGraduated = []
function graduateStudent(student, index) {
let object = { name: student, position: index + 1}
nowGraduated[index] = object
}
stillStudent.forEach((name, index) => graduateStudent(name, index));
console.log(nowGraduated);
/*
[
{ name: "anna", position: 1},
{ name: "beth", position: 2},
{ name: "chris", position: 3},
{ name: "daniel", position: 4},
{ name: "ethan", position: 5}]
]
*/
如何使用数组参数检查数组中的下一项
在某些时候,教师需要检查列表中是否有下一个特定项目。在这种情况下,教师需要对整个列表有一个广泛的了解。这样,他就可以判断是否有下一个学生需要调用。
在我们的 JavaScript 代码中,我们可以复制这一点,因为回调函数也可以访问数组(第三个)参数。该参数表示目标数组,即名称。
我们检查数组中是否有下一项(学生)。如果有,我们将字符串 positive
传递给 nextItem
变量。如果没有,我们将字符串 negative
传递给变量。然后对于每次迭代,我们检查该学生是否确实是最后一个。
names = ["anna", "beth", "chris", "daniel", "ethan"]
function rollCall(name, index, array) {
let nextItem = index + 1 < array.length ? "postive" : "negative"
console.log(`Is the number ${index + 1} student - ${name} present? Yes!. Is there a next student? ${nextItem}!`);
}
names.forEach((name, index, array) => rollCall(name, index, array))
/*
"Is the number 1 student - anna present? Yes!. Is there a next student? postive!"
"Is the number 2 student - beth present? Yes!. Is there a next student? postive!"
"Is the number 3 student - chris present? Yes!. Is there a next student? postive!"
"Is the number 4 student - daniel present? Yes!. Is there a next student? postive!"
"Is the number 5 student - ethan present? Yes!. Is there a next student? negative!"
*/
你不能退出 forEach
循环,所以使用 every()
代替
还记得我提到的,本质上,你不能跳出(也就是退出)forEach
循环吗?一旦启动,它将一直运行,直到到达数组中的最后一项。所以如果你插入一个 break
语句,它会返回一个 SyntaxError
:
let numbers = [2, 4, 5, 8, 12]
let odd = 5;
numbers.forEach(function(number) {
if (number === odd) {
break; // oops, this isn't gonna work!
}
})
通常,如果你在到达最后一个项目之前最终实现了你想要实现的目标,那么你会希望跳出循环。在上面的示例中,我们已经找到了奇数(5),因此无需继续迭代剩余的项目(8 和 12)。
如果你想在某些条件下跳出循环,则必须使用以下任何一种方法:
for
循环for…of
或for…in
循环Array.some()
Array.every()
Array.find()
以下是使用 Array.every()
跳出循环的方法:
let numbers = [2, 4, 5, 8, 12]
let odd = 5;
numbers.every(number => {
if (number == odd) {
return false;
}
console.log(number);
return true;
});
// 2 4
总结
在本教程中,我介绍了 forEach
方法,通过一个简单的类比说明了它的工作原理,并且还提供了一些在 JavaScript 代码中使用它的实际示例。
希望你能从这篇文章中得到一些有用的东西。
如果你想了解有关 Web 开发的更多信息,请随时访问我的博客。
感谢你阅读本文!
P/S:如果你正在学习 JavaScript,我创建了一本电子书,其中包含手绘数字笔记的 50 个 JavaScript 主题。在这里查看。
原文:JavaScript Array.forEach() Tutorial – How to Iterate Through Elements in an Array,作者:Kingsley Ubah