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
答案 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/
要记住几件事:
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 foundEntry
从updateAndReturnMatch
返回。
有时这是你想要的,但通常上面的模式可以用Array#find
替换,这是ES2015中的新功能,但可以为旧版浏览器填充:
function updateAndReturnMatch(array, value) {
var foundEntry = array.find(function(entry) {
return entry.someProp == value;
});
if (foundEntry) {
++foundEntry.count;
}
return foundEntry;
}