Я пытаюсь создать функцию, которая принимает массив и функцию обратного вызова. Функция должна возвращать истину, если все значения в массиве, переданном в обратный вызов, возвращают истину, в противном случае - ложь. Но я не уверен, что делаю неправильно
const every = function(arr, callback) {
arr.forEach(function(element) {
if (!callback(element)) {
return false
}
})
return true
};
every([1, 2, 3, 4, 5], function(val) {
return val < 2
});
ожидаемые результаты => ложь но я становлюсь правдой.
Это только я, или обратный вызов передается неверно синтаксически? {} в конце выглядит странно
Array.prototype имеет every, который делает то, что вы хотите, например [1, 2, 3, 4, 5].every(val => val < 2)@ ic3b3rg Он явно пытается понять, как самому реализовать подобную функцию.
@Barmar Не уверен, что он знает о Array.prototype.every
Я предполагаю, что это академическое упражнение, так что это не имеет значения.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете использовать для этого reduce (). Если вы основываете свое сокращение на истине и результате обратного вызова, оно будет оставаться верным, пока обратный вызов будет истинным. Если обратный вызов является ложным, проверка truth в условном выражении приведет к короткому замыканию логики, и обратный вызов больше не будет выполняться. Тем не менее, он будет перебирать все элементы.
Он также возвращает истину для пустого массива, что, похоже, соответствует вашей исходной логике.
const every = function(arr, callback) {
return arr.reduce(function(truth, element){
return truth && callback(element);
}, true);
};
console.info(
every([1, 2, 3, 4, 5], function(val){return val < 2})
);
console.info(
every([], function(val){return val < 2})
);Хотя, как указал @ ic3b3rg, Array.prototype.every существует и, похоже, имеет ту же поддержку браузера, что и Array.prototype.reduce
Возврат false из обратного вызова forEach также не приведет к возврату функции every. Вместо этого он просто продолжит работу итератора forEach.
Самым простым решением вашей проблемы будет цикл for...of, поскольку он позволяет использовать шаблон return, аналогичный вашему фрагменту:
const every = function(arr, callback) {
for (const element of arr) {
if (!callback(element)) {
return false;
}
}
return true;
};
console.info(every([1, 2, 3, 4, 5], function(val) {
return val < 2;
}));Примечание: Используя конструкцию цикла everyвозвращается рано. Метод массивов forEach всегда выполняется до тех пор, пока не будут посещены все элементы массива, но цикл прерывается сразу после того, как один элемент не прошел проверку. Обычный цикл for даст вам такое же преимущество в производительности.
Это полезно знать. Мне было интересно, почему цикл продолжает повторяться даже после выполнения условия. Спасибо за это!
arr.forEach(function(element) {
return false
})
Это внутренняя функция, возвращающая false, которая не влияет на внешнюю функцию (в этой ситуации) вы должны создать новую переменную внутри внешней функции и вместо того, чтобы возвращать false во внутренней функции, измените переменную в конце просто верните переменную
const every = function(arr, callback) {
let isEvery = true
arr.forEach(function(element) {
if (!callback(element)) { // or just isEvery = isEvery && statement
isEvery = false
}
})
return isEvery
};
Я бы рекомендовал использовать простой цикл for:
const every = (arr, callback) => {
for (let i = 0; i < arr.length; i++){
if (callback(arr[i]) === false){
return false;
}
}
return true;
};
console.info(every([1, 2, 3, 4, 5], function(val){return val < 2}));
Возврат внутри обратного вызова к методу forEach вызывает совершенно ничего в функции, в которой был вызван этот метод. Я бы предложил отфильтровать массив и проверить полученную длину. В качестве альтернативы, более новые версии JavaScript фактически имеют каждый метод для массивов: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…