【问题标题】:Why does this forEach return undefined when using a return statement为什么在使用return语句时这个forEach返回未定义
【发布时间】:2011-11-04 19:19:17
【问题描述】:
Object.prototype.e = function() {
    [].forEach.call(this, function(e) {
        return e;
    });
}; 
var w = [1,2];

w.e(); // undefined

但如果我改用 alert 就可以了

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

w.e(); // 1, 2

【问题讨论】:

  • 你希望第一个做什么?
  • 我不明白,你想用.map吗?请不要在Object.prototype 上放置可枚举的属性!
  • @Bergi 老实说,我不记得我当时在想什么。我是初学者,对不起。大声笑

标签: javascript


【解决方案1】:

因为

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 中返回。

【讨论】:

    【解决方案2】:

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

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

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

    但调用updateAndReturnMatch 会得到undefined,即使找到并更新了该条目。

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

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

    【讨论】:

    • @squint:是的,我在评论中指出了这一点。但我想不出更好的例子。我缺乏创造力。 :-|
    • @squint:我想我想出了一个更好的例子。
    【解决方案3】:

    我意识到这是一个老问题,但是当你搜索这个主题时,这是在谷歌上出现的第一件事,我会提到你可能正在寻找的是 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 不保证您的数据将按任何特定顺序返回。
    • 您的变量仍将引用索引,而不是存储在该索引处的实际值。
    • 另请参阅下面的 cmets,了解如何将其与数组一起使用。

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

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

    【讨论】:

    • 也许不是个好主意:stackoverflow.com/questions/500504/…
    • 一个很好的区别是 (for.. in) 可以在数组(和类似的数据类型)上被误用,但在用于其他用户定义的对象(尤其是像 JSON 这样的数据类型),至少在我经常使用的编码圈中没有。使用 (for...in) 时最重要的事情是跟踪谁在触摸您的对象以及他们是否将任何额外的属性附加到它们上。除此之外,唯一真正的缺点是 JS 怪癖可能会让您大吃一惊。
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 2023-01-24
      • 2022-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-26
      • 2021-02-06
      • 2013-11-29
      相关资源
      最近更新 更多