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

Javascript 为什么在使用return语句时,这个forEach返回undefined,javascript,Javascript,但如果我改用alert,这会起作用 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 这是一

但如果我改用alert,这会起作用

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
这是一个回调。Array.forEach很可能以这种方式调用它:

function(e) {
    return e;
}

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

函数
e()
没有返回任何内容;内部匿名函数返回它的
e
值,但是调用方忽略了该返回值(调用方是
function e()
(“e”的多次使用会不会变得更混乱?)

我意识到这是一个老问题,但是当你搜索这个主题时,这是谷歌上出现的第一件事,我要提到的是,您可能正在寻找的是javascript的。。在循环中,它在许多其他语言中的行为更接近于C语言、C++等,

return callback.call();

有几件事需要记住:

  • for..in不保证您的数据将按任何特定顺序返回
  • 变量仍将引用索引,而不是该索引中存储的实际值
  • 另请参见下面有关将此用于阵列的注释
编辑:for..in将(至少)向对象的原型返回添加的属性。如果这是不需要的,您可以通过在附加检查中包装逻辑来纠正此行为:


您的示例有点奇怪,但随着这个问题成为规范的“从
forEach
返回”问题,让我们用更简单的方法来演示这个问题:

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

for(var x in object) {
    if(object.hasOwnProperty(x)) {
        console.log(x + ": " + object[x]);   
    }
}
但是调用
updateAndReturnMatch
会给我们提供
未定义的
,即使找到并更新了条目也是如此

原因是
forEach
回调中的
return
从回调返回,而不是从
updateAndReturnMatch
返回。记住,回调是一个函数<函数中的code>return
从该函数返回,而不是从包含该函数的函数返回

要从
updateAndReturnMatch
返回,我们需要记住条目并中断循环。由于您无法中断
forEach
循环,因此我们将使用
some

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

你希望第一个做什么?我不明白,你想用
.map
?请不要在
对象上放置可枚举属性。prototype
@贝基,我真的不记得我当时在想什么。对不起,我是初学者。LOL也许不是一个好主意:一个好的区别是(for..in)可以在数组(和类似的数据类型)上被误用,但在其他用户定义的对象(特别是涉及JSON之类的数据类型)上使用时,在很大程度上并没有被认为是不好的做法,至少在我经常使用的编码圈中没有。使用(for…in)时最重要的一点是跟踪谁在触摸对象,以及对象是否附加了任何额外属性。除此之外,唯一真正的缺点是JS的怪癖可能会让你大吃一惊。@Skint:是的,我在评论中提到了这一点。但我想不出更好的例子了。我缺乏创造力-|@斜视:我想我想出了一个更好的例子。
for(var x in object) {
    if(object.hasOwnProperty(x)) {
        console.log(x + ": " + object[x]);   
    }
}
function updateAndReturnMatch(array, value) {
    array.forEach(function(entry) {
        if (entry.someProp == value) {
           ++entry.count;
           return entry;
        }
    });
}
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;
}
function updateAndReturnMatch(array, value) {
    var foundEntry = array.find(function(entry) {
        return entry.someProp == value;
    });
    if (foundEntry) {
        ++foundEntry.count;
    }
    return foundEntry;
}