简体   繁体   中英

Unexpected Behavior of Return Statement inside forEach() Loop in JavaScript

My question relates to a JavaScript function I have written that seems to be behaving a bizarre way. In summary, the function execution seems to go on even after a return statement is encountered - it's as if the return statement inside a forEach loop is ignored. This is difficult to make sense of, and is not how it happens in any of the languages I have seen before.

Presenting a code snippet below - I have tried to make the code, logging and comments as focused and descriptive as possible so that the reader can easily identify the issue. However, I am sharing a detailed description of the problem as well if you'd prefer not to jump to the code directly.

In the code I have shared, the function substituteWithMainColor() takes a string value named color as argument. It matches it against each element of an array (called substitutionArray ) of object literals, where each such object contains a member string called mainColor and member array called variations . If the function finds the color argument in any of the variations arrays, then it returns the corresponding mainColor of the object in which the match was found. If no match is found in any of the objects, then the function returns the original value passed as argument.

In my example, an argument "Cyan" is passed to the function substituteWithMainColor() . Since the array substitutionArray contains "Cyan" as one of the strings in the variations array of its third item, a match is found ( and the logs show it). However, at this point, instead of returning with the matched mainColor value "Blue" as expected, the function ignores the return statement inside the forEach() loop and keeps on executing further iterations of the forEach loop (the logs show this, too). Eventually it executes the final return statement which is after the forEach() loop, and returns the original color value, which is erroneous.

Can someone please help me understand what might be going on?

 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 is not the same an a normal for loop. You're essentially passing a function to be executed every loop, so your return acts in the scope of that function , not the loop.

It's a little like this:

for(let i = 0; i < 5; i++) {
    foo();
}

function foo() {
    // do something
    return true;
}

You're probably looking for something like find() ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find )

substitutionArray.find(item => item.variations.includes(color)).mainColor;

Note that the return of the find it the item inside substitutionArray , so you have to extract the mainColor afterwards. If there's a chance that you won't find it, add a null check

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM