在 JavaScript 中 forEach() 循环中 Return 语句的意外行为
Unexpected Behavior of Return Statement inside forEach() Loop in JavaScript
我的问题与我编写的 JavaScript 函数有关,该函数的行为方式似乎很奇怪。总之,即使在遇到 return
语句后,函数执行似乎仍在继续 - 就好像 forEach
循环中的 return
语句被忽略了。这很难理解,而且在我以前见过的任何语言中都不是这样。
在下面展示一个代码片段 - 我已尝试使代码、日志记录和评论尽可能具有重点和描述性,以便 reader 可以轻松识别问题。但是,如果您不想直接跳转到代码,我也会分享问题的详细描述。
在我分享的代码中,函数 substituteWithMainColor()
接受一个名为 color
的字符串值作为参数。它将它与对象文字数组(称为 substitutionArray
)的每个元素进行匹配,其中每个此类对象包含一个名为 mainColor
的成员字符串和名为 variations
的成员数组。如果函数在任何 variations
数组中找到 color
参数,则它 returns 找到匹配项的对象的相应 mainColor
。如果在任何对象中都找不到匹配项,则函数 returns 将原始值作为参数传递。
在我的示例中,参数 "Cyan" 被传递给函数 substituteWithMainColor()
。由于数组 substitutionArray
包含 "Cyan" 作为其第三项 variations
数组中的字符串之一,因此找到了一个匹配项(并且日志显示了它).然而,此时,函数并没有像预期的那样返回匹配的 mainColor
值 "Blue",而是忽略了 [=30= 中的 return
语句] 循环并继续执行 forEach
循环的进一步迭代(日志也显示了这一点)。最终它执行 forEach()
循环之后的最终 return
语句,并且 returns 原始 color
值,这是错误的。
有人可以帮助我了解可能发生的情况吗?
const substitutionArray = [
{ mainColor: "Red", variations: ["Magenta", "Orange", "Crimson", "Coral", "Maroon"] },
{ mainColor: "Blue", variations: ["Purple", "Violet", "Cyan"] },
{ mainColor: "Green", variations: ["Teal", "Lime", "Aquamarine", "Olive"] }
]
function substituteWithMainColor(color) {
logToPage(`In substituteWithMainColor() function. Input: ${color}`);
substitutionArray.forEach(item => {
logToPage(`Testing input ${color} against variations of ${item.mainColor}`)
if (item.variations.includes(color)) {
logToPage(`FOUND MATCH for ${color} - Main color: ${item.mainColor}. Returning ${item.mainColor}`);
return item.mainColor; //Function should return from here if match is found.
}
});
logToPage(`No matches found for ${color}. Returning ${color}`)
return color; //No matches found
}
function writeToPage(text) { document.body.innerHTML += `<div class = "content"> ${text} </div>`; }
function logToPage(text) { document.body.innerHTML += `<div class = "log"> ${text} </div >`; }
const colorName = "Cyan";
writeToPage(`Original Color: ${colorName}`)
writeToPage(`Returned Value: ${substituteWithMainColor(colorName)}`); // "Blue should be returned"
.content {
outline: 1px solid rgb(161, 189, 135);
padding: 5px;
margin: 5px;
color: rgb(255, 127, 80);
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 16px;
font-weight: bold;
}
.log {
outline: 1px solid #ccc;
padding: 5px;
margin: 5px;
color: rgb(85, 91, 122);
font-family: Verdana, Geneva, Tahoma, sans-serif;
font-size: 12px;
}
A forEach
与正常的 for
循环不同。您实际上是在传递一个要在每个循环中执行的函数,因此您的 return
在该函数 的范围内起作用 ,而不是循环。
有点像这样:
for(let i = 0; i < 5; i++) {
foo();
}
function foo() {
// do something
return true;
}
您可能正在寻找类似 find()
(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
的内容
substitutionArray.find(item => item.variations.includes(color)).mainColor;
请注意,find
的 return 是 substitutionArray
中的 item
,因此您必须在之后提取 mainColor
。如果您有可能找不到它,请添加空检查
我的问题与我编写的 JavaScript 函数有关,该函数的行为方式似乎很奇怪。总之,即使在遇到 return
语句后,函数执行似乎仍在继续 - 就好像 forEach
循环中的 return
语句被忽略了。这很难理解,而且在我以前见过的任何语言中都不是这样。
在下面展示一个代码片段 - 我已尝试使代码、日志记录和评论尽可能具有重点和描述性,以便 reader 可以轻松识别问题。但是,如果您不想直接跳转到代码,我也会分享问题的详细描述。
在我分享的代码中,函数 substituteWithMainColor()
接受一个名为 color
的字符串值作为参数。它将它与对象文字数组(称为 substitutionArray
)的每个元素进行匹配,其中每个此类对象包含一个名为 mainColor
的成员字符串和名为 variations
的成员数组。如果函数在任何 variations
数组中找到 color
参数,则它 returns 找到匹配项的对象的相应 mainColor
。如果在任何对象中都找不到匹配项,则函数 returns 将原始值作为参数传递。
在我的示例中,参数 "Cyan" 被传递给函数 substituteWithMainColor()
。由于数组 substitutionArray
包含 "Cyan" 作为其第三项 variations
数组中的字符串之一,因此找到了一个匹配项(并且日志显示了它).然而,此时,函数并没有像预期的那样返回匹配的 mainColor
值 "Blue",而是忽略了 [=30= 中的 return
语句] 循环并继续执行 forEach
循环的进一步迭代(日志也显示了这一点)。最终它执行 forEach()
循环之后的最终 return
语句,并且 returns 原始 color
值,这是错误的。
有人可以帮助我了解可能发生的情况吗?
const substitutionArray = [
{ mainColor: "Red", variations: ["Magenta", "Orange", "Crimson", "Coral", "Maroon"] },
{ mainColor: "Blue", variations: ["Purple", "Violet", "Cyan"] },
{ mainColor: "Green", variations: ["Teal", "Lime", "Aquamarine", "Olive"] }
]
function substituteWithMainColor(color) {
logToPage(`In substituteWithMainColor() function. Input: ${color}`);
substitutionArray.forEach(item => {
logToPage(`Testing input ${color} against variations of ${item.mainColor}`)
if (item.variations.includes(color)) {
logToPage(`FOUND MATCH for ${color} - Main color: ${item.mainColor}. Returning ${item.mainColor}`);
return item.mainColor; //Function should return from here if match is found.
}
});
logToPage(`No matches found for ${color}. Returning ${color}`)
return color; //No matches found
}
function writeToPage(text) { document.body.innerHTML += `<div class = "content"> ${text} </div>`; }
function logToPage(text) { document.body.innerHTML += `<div class = "log"> ${text} </div >`; }
const colorName = "Cyan";
writeToPage(`Original Color: ${colorName}`)
writeToPage(`Returned Value: ${substituteWithMainColor(colorName)}`); // "Blue should be returned"
.content {
outline: 1px solid rgb(161, 189, 135);
padding: 5px;
margin: 5px;
color: rgb(255, 127, 80);
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 16px;
font-weight: bold;
}
.log {
outline: 1px solid #ccc;
padding: 5px;
margin: 5px;
color: rgb(85, 91, 122);
font-family: Verdana, Geneva, Tahoma, sans-serif;
font-size: 12px;
}
A forEach
与正常的 for
循环不同。您实际上是在传递一个要在每个循环中执行的函数,因此您的 return
在该函数 的范围内起作用 ,而不是循环。
有点像这样:
for(let i = 0; i < 5; i++) {
foo();
}
function foo() {
// do something
return true;
}
您可能正在寻找类似 find()
(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
substitutionArray.find(item => item.variations.includes(color)).mainColor;
请注意,find
的 return 是 substitutionArray
中的 item
,因此您必须在之后提取 mainColor
。如果您有可能找不到它,请添加空检查