Why does this forEach return undefined when using a return statement

前端 未结 4 1541
自闭症患者
自闭症患者 2020-12-04 01:50
Object.prototype.e = function() {
    [].forEach.call(this, function(e) {
        return e;
    });
}; 
var w = [1,2];

w.e(); // undefined

But thi

4条回答
  •  眼角桃花
    2020-12-04 02:26

    Your example is a bit odd, but as this question is becoming the canonical "return from forEach" question, let's use something simpler to demonstrate the problem:

    Here, we have a function that checks the entries in an array to see if someProp matches value and, if so, increments the count on the entry and returns the entry:

    function updateAndReturnMatch(array, value) {
        array.forEach(function(entry) {
            if (entry.someProp == value) {
               ++entry.count;
               return entry;
            }
        });
    }
    

    But calling updateAndReturnMatch gives us undefined, even if the entry was found and updated.

    The reason is that the return inside the forEach callback returns from the callback, not from updateAndReturnMatch. Remember, the callback is a function; return in a function returns from that function, not the one containing it.

    To return from updateAndReturnMatch, we need to remember the entry and break the loop. Since you can't break a forEach loop, we'll use some instead:

    function updateAndReturnMatch(array, value) {
        var foundEntry;
        array.some(function(entry) {
            if (entry.someProp == value) {
               foundEntry = entry;
               ++foundEntry.count;
               return true; // <== Breaks out of the `some` loop
            }
        });
        return foundEntry;
    }
    

    The return true returns from our some callback, and the return foundEntry returns from updateAndReturnMatch.

    Sometimes that's what you want, but often the pattern above can be replaced with Array#find, which is new in ES2015 but can be shimmed for older browsers:

    function updateAndReturnMatch(array, value) {
        var foundEntry = array.find(function(entry) {
            return entry.someProp == value;
        });
        if (foundEntry) {
            ++foundEntry.count;
        }
        return foundEntry;
    }
    

提交回复
热议问题