Ответ 1
Функция e()
ничего не возвращает; внутренняя анонимная функция возвращает значение e
, но возвращаемое значение игнорируется вызывающим абонентом (вызывающий function e()
(и может ли несколько использования 'e' более запутывать?))
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
Функция e()
ничего не возвращает; внутренняя анонимная функция возвращает значение e
, но возвращаемое значение игнорируется вызывающим абонентом (вызывающий function e()
(и может ли несколько использования 'e' более запутывать?))
Я понимаю, что это старый вопрос, но поскольку это первое, что появляется в google при поиске по этой теме, я упомянул, что то, что вы, вероятно, ищете, - это javascript for.. in loop, который ведет себя ближе к каждому из них на многих других языках, таких как С#, С++ и т.д.
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]);
}
}
Потому что
function(e) {
return e;
}
является обратным вызовом. Array.forEach скорее всего называет его таким образом:
function forEach(callback) {
for(i;i<length;i++) {
item = arr[i];
callback.call(context, item, i, etc.)
}
}
поэтому вызывается обратный вызов, но возврат не идет нигде. Если callback вызывались как:
return callback.call();
он будет возвращать из forEach по первому элементу массива.
Ваш пример немного странный, но поскольку этот вопрос становится каноническим вопросом "возврат из forEach
", попробуйте использовать что-то более простое, чтобы продемонстрировать проблему:
Здесь у нас есть функция, которая проверяет записи в массиве, чтобы увидеть, соответствует ли 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;
}