在 JavaScript 中,您經(jīng)常需要遍歷數(shù)組集合并為每次迭代執(zhí)行回調(diào)方法。JS 開發(fā)人員通常會使用一種有用的方法來執(zhí)行此操作:forEach()方法。
該forEach()方法為它在數(shù)組內(nèi)迭代的每個元素調(diào)用一次指定的回調(diào)函數(shù)。就像其他數(shù)組迭代器如map和filter一樣,回調(diào)函數(shù)可以接受三個參數(shù):
- 當(dāng)前元素:這是當(dāng)前正在迭代的數(shù)組中的項目。
- 它的索引:這是該項目在數(shù)組中的索引位置
- 目標(biāo)數(shù)組:這是正在迭代的數(shù)組
該forEach方法不會像filter,map和等其他迭代器那樣返回新數(shù)組sort。相反,該方法返回undefined自身。所以它不像其他方法那樣可鏈接。
另一件事forEach是您不能終止循環(huán)(使用 break 語句)或使其跳過一次迭代(使用 continue 語句)。換句話說,你無法控制它。
終止forEach循環(huán)的唯一方法是在回調(diào)函數(shù)中拋出異常。別擔(dān)心,我們很快就會在實踐中看到所有這些。
如何forEach()在 JavaScript 中使用方法
想象一下,一群學(xué)生排隊進(jìn)行例行點名。班級協(xié)調(diào)員穿過隊伍并喊出每個學(xué)生的名字,同時標(biāo)記他們是否在場。
需要注意的是,協(xié)調(diào)員不會改變學(xué)生在行中的順序。在完成點名后,他還將他們保持在同一條線上。他所做的就是對每個人執(zhí)行一個操作(他的檢查)。
在下面的示例中,記住這個場景,我們將看到如何使用forEachJavaScript 中的方法來解決現(xiàn)實世界的問題。
forEach() JavaScript 中的方法示例
如何刪除數(shù)組中的第一個奇數(shù) forEach()
在這個例子中,我們有一個數(shù)組,它在第一個位置有一個奇數(shù),后面有幾個偶數(shù)。但是我們只希望這個數(shù)組中的數(shù)字是偶數(shù)。所以我們將使用forEach()循環(huán)從數(shù)組中刪除奇數(shù):
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在數(shù)組內(nèi)部循環(huán)的每個學(xué)生執(zhí)行一個函數(shù)。該rollcall函數(shù)只是將與每個學(xué)生相關(guān)的字符串記錄到控制臺。
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!"
*/
在這個例子中,我們關(guān)于每個學(xué)生的唯一信息是他們的名字。然而,我們也想知道每個學(xué)生使用什么代詞。換句話說,我們想要為每個學(xué)生定義一個代詞屬性。
所以我們將每個學(xué)生定義為一個具有兩個屬性的對象,名稱和代詞:
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!"
*/
我們將每個學(xué)生的點名消息記錄到控制臺,然后我們執(zhí)行檢查以查看學(xué)生使用的代詞,最后我們將準(zhǔn)確的代詞作為字符串的一部分動態(tài)傳遞。
如何使用forEach()JavaScript將數(shù)組復(fù)制到新數(shù)組中
經(jīng)過三年的學(xué)習(xí),現(xiàn)在是每個學(xué)生畢業(yè)的時候了。在我們的 JavaScript 中,我們定義了兩個數(shù)組:stillStudent和nowGraduated。正如您可能已經(jīng)猜到的那樣,stillStudent在學(xué)生畢業(yè)之前抓住他們。
然后forEach循環(huán)接收每個學(xué)生并調(diào)用其graduateStudent上的函數(shù)。
在這個函數(shù)中,我們構(gòu)造了一個具有兩個屬性的對象:學(xué)生的姓名以及他們畢業(yè)的位置。然后我們將新對象傳遞給nowGraduated數(shù)組。那個時候,學(xué)生已經(jīng)畢業(yè)了。
此示例還演示了如何使用該forEach()方法將數(shù)組復(fù)制到新數(shù)組中。
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參數(shù)檢查數(shù)組中的下一項
在某些時候,教師需要檢查列表中是否有下一個特定項目。在這種情況下,教師需要對整個列表有一個廣泛的了解。這樣,他就可以判斷是否有下一個學(xué)生需要調(diào)用。
在我們的 JavaScript 中,我們可以復(fù)制這一點,因為回調(diào)函數(shù)也可以訪問array(第三個)參數(shù)。該參數(shù)表示目標(biāo)數(shù)組,即name.
我們檢查數(shù)組中是否有下一項(學(xué)生)。如果有,我們將字符串傳遞positive給nextItem變量。如果沒有,我們將字符串傳遞negative給變量。然后對于每次迭代,我們檢查該學(xué)生是否確實是最后一個。
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循環(huán),所以用every()相反
還記得我提到的,本質(zhì)上,你不能跳出(又名退出)forEach循環(huán)?一旦啟動,它將一直運行直到到達(dá)數(shù)組中的最后一項。因此,如果您插入一條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!
}
})
通常,如果您在到達(dá)最后一個項目之前最終實現(xiàn)了您想要實現(xiàn)的目標(biāo),那么您會希望跳出循環(huán)。在上面的示例中,我們已經(jīng)找到了奇數(shù) (5),因此無需繼續(xù)迭代剩余的項目(8 和 12)。
如果您想在某些情況下跳出循環(huán),則必須使用以下任何一種方法:
- for 環(huán)形
- for…of或for…in循環(huán)
- Array.some()
- Array.every()
- Array.find()
以下是如何跳出循環(huán)的方法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
總結(jié)
在本教程中,我介紹了該forEach方法,并通過一個簡單的類比說明了它的工作原理,并且還提供了一些在 JavaScript 代碼中使用它的實際示例。
希望你能從這篇文章中得到一些有用的東西。