在JavaScript中,你经常需要对一个数组集合进行迭代,并为每次迭代执行一个回调方法。有一个有用的方法,JS开发者通常用来做这个:forEach() 方法。
forEach() 方法在数组中每迭代一个元素就会调用一个指定的回调函数。就像其他数组迭代器,如map 和filter ,回调函数可以接收三个参数:
- 当前元素:这是当前被迭代的数组中的一个项目。
- 它的索引:这是该项目在数组中的索引位置。
- 目标数组:这是正在被迭代的数组。
forEach 方法并不像其他迭代器如filter,map 和sort 那样返回一个新的数组。相反,该方法返回undefined 本身。所以它不像其他方法那样是可以连锁的。
关于forEach ,还有一点是,你不能终止循环(用break语句)或使其跳过一个迭代(用continue语句)。换句话说,你不能控制它。
终止forEach 循环的唯一方法是在回调函数中抛出一个异常。别担心,我们很快就会在实践中看到这一切。
如何在JavaScript中使用forEach() 方法
想象一下,一群学生排着队等待例行点名。班级协调人在队伍中走来走去,叫出每个学生的名字,同时标明他们是出席还是缺席。
值得注意的是,协调人并没有改变学生在队伍中的顺序。在点名结束后,他也会将他们保持在同一队伍中。他所做的只是对他们每个人执行一个动作(他的检查)。
在下面的例子中,记住这个场景,我们将看到你如何使用JavaScript中的forEach 方法来解决现实世界的问题。
forEach() JavaScript中的方法实例
如何在一个数组中删除第一个奇数?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}]
]
*/
如何用array 参数检查数组中的下一个项目
在某些时候,老师需要检查列表中是否有一个特定的项目在列表的下一个位置。在这种情况下,老师需要对整个列表有一个广阔的视野。这样,他就可以知道是否有下一个学生需要调用。
在我们的JavaScript中,我们可以复制这一点,因为回调函数也可以访问array (第三个)参数。这个参数代表目标数组,也就是name 。
我们检查数组中是否有下一个项目(学生)。如果有,我们将字符串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…inArray.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开发的知识,欢迎访问我的 博客。
谢谢你的阅读,再见。