javascript 为什么在使用 return 语句时 forEach 返回 undefined

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7209794/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 23:18:13  来源:igfitidea点击:

Why does this forEach return undefined when using a return statement

javascript

提问by 0x499602D2

Object.prototype.e = function() {
    [].forEach.call(this, function(e) {
        return e;
    });
}; 
var w = [1,2];

w.e(); // undefined

But this works if I use alert instead

但是如果我改用警报,这会起作用

// ...
[].forEach.call(this, function(e) {
    alert(e);
});
// ...

w.e(); // 1, 2

采纳答案by Stephen P

The function e()isn't returning anything; the inner anonymous function is returning itsevalue but that return value is being ignored by the caller (the caller being function e()(and can the multiple uses of 'e' get any more confusing?))

该函数e()没有返回任何东西;内部匿名函数正在返回e值,但该返回值被调用者忽略(调用者是function e()(并且“e”的多次使用会变得更加混乱吗?))

回答by danShumway

I realize this is an old question, but as it's the first thing that comes up on google when you search about this topic, I'll mention that what you're probably looking for is javascript's for.. in loop, which behaves closer to the for-each in many other languages like C#, C++, etc...

我意识到这是一个老问题,但是当您搜索此主题时,这是 google 上出现的第一件事,我会提到您可能正在寻找的是 javascript 的 for.. in 循环,它的行为更接近于许多其他语言中的 for-each,如 C#、C++ 等......

for(var x in enumerable) { /*code here*/ }

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/for...in

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/for...in

http://jsfiddle.net/danShumway/e4AUK/1/

http://jsfiddle.net/danShumway/e4AUK/1/

A couple of things to remember :

需要记住的几件事:

  • for..in will not guarantee that your data will be returned in any particular order.
  • Your variable will still refer to the index, not the actual value stored at that index.
  • Also see below comments about using this with arrays.
  • for..in 不保证您的数据将按任何特定顺序返回。
  • 您的变量仍将引用索引,而不是存储在该索引处的实际值。
  • 另请参阅以下有关将其与数组一起使用的评论。

edit: for..in will return (at the least) added properties to the prototype of an object. If this is undesired, you can correct for this behavior by wrapping your logic in an additional check:

编辑: for..in 将(至少)返回添加到对象原型的属性。如果这是不希望的,您可以通过将您的逻辑包装在额外的检查中来纠正此行为:

for(var x in object) {
    if(object.hasOwnProperty(x)) {
        console.log(x + ": " + object[x]);   
    }
}

回答by T.J. Crowder

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:

你的例子有点奇怪,但随着这个问题正在成为规范的“从forEach”问题,让我们用更简单的东西来演示这个问题:

Here, we have a function that checks the entries in an array to see if somePropmatches valueand, if so, increments the counton the entry and returns the entry:

在这里,我们有一个函数来检查数组中的条目是否someProp匹配value,如果匹配,则增加count条目上的 并返回条目:

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

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

但是即使找到并更新了条目,调用也会updateAndReturnMatch为我们提供undefined

The reason is that the returninside the forEachcallback returns from the callback, not from updateAndReturnMatch. Remember, the callback is a function; returnin a function returns from thatfunction, not the one containing it.

其原因是,return里面forEach从回调函数返回的回调,而不是从updateAndReturnMatch。记住,回调是一个函数;return在一个函数中从那个函数返回,而不是包含它的那个。

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

要从 返回updateAndReturnMatch,我们需要记住条目并打破循环。由于您无法打破forEach循环,我们将some改为使用:

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 truereturns from our somecallback, and the return foundEntryreturns from updateAndReturnMatch.

return true我们返回some的回调,而return foundEntry从回报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:

有时这就是你想要的,但通常上面的模式可以替换为Array#find,这是 ES2015 中的新内容,但可以为旧浏览器填充:

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

回答by Joe

Because

因为

function(e) {
    return e;
}

is a callback. Array.forEach most likely calls it in this fashion:

是回调。Array.forEach 很可能以这种方式调用它:

function forEach(callback) {
    for(i;i<length;i++) {
        item = arr[i];
        callback.call(context, item, i, etc.)
    }
}

so the call back is called, but the return doesn't go anywhere. If callback were called like:

所以回调被调用,但返回不会去任何地方。如果回调被调用如下:

return callback.call();

the it would return out of forEach on the first item in the array.

它将在数组中的第一项上从 forEach 返回。