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

时间:2011-08-26 19:45:45

标签: javascript

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

w.e(); // undefined

但如果我使用警报

,则此方法有效
// ...
[].forEach.call(this, function(e) {
    alert(e);
});
// ...

w.e(); // 1, 2

4 个答案:

答案 0 :(得分:8)

我意识到这是一个老问题,但是当你搜索这个主题时,谷歌首次出现这个问题,我会提到你可能正在寻找的是javascript for ... in循环,在C#,C ++等许多其他语言中表现得更接近for-each ...

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

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

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

要记住几件事:

  • for..in不保证您的数据将以任何特定顺序返回。
  • 您的变量仍将引用索引,而不是存储在该索引处的实际值。
  • 另请参阅以下有关使用数组的注释。

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

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

答案 1 :(得分:7)

函数e()没有返回任何内容;内部匿名函数返回 e值,但调用者忽略该返回值(调用者为function e()(可以多次使用'e'获取更令人困惑的?))

答案 2 :(得分:6)

因为

function(e) {
    return e;
}

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

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

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

return callback.call();

它将从数组中的第一个项目返回forEach。

答案 3 :(得分:6)

你的例子有点奇怪,但随着这个问题成为规范&#34;从forEach返回&#34;问题,让我们使用更简单的东西来证明问题:

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

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

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

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

要从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;
}

return true从我们的some回调中返回,return foundEntryupdateAndReturnMatch返回。

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

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