JavaScript Array.forEach()教程--如何迭代数组中的元素

79 阅读4分钟

在JavaScript中,你经常需要对一个数组集合进行迭代,并为每次迭代执行一个回调方法。有一个有用的方法,JS开发者通常用来做这个:forEach() 方法。

forEach() 方法在数组中每迭代一个元素就会调用一个指定的回调函数。就像其他数组迭代器,如mapfilter ,回调函数可以接收三个参数:

  • 当前元素:这是当前被迭代的数组中的一个项目。
  • 它的索引:这是该项目在数组中的索引位置。
  • 目标数组:这是正在被迭代的数组。

forEach 方法并不像其他迭代器如filter,mapsort 那样返回一个新的数组。相反,该方法返回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中,我们定义了两个数组:stillStudentnowGraduated 。正如你可能猜到的那样,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)。

如果你想在某些条件下跳出循环,那么你必须使用以下任何一种方法:

下面是你如何用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开发的知识,欢迎访问我的 博客

谢谢你的阅读,再见。