Проблема с функцией обратного вызова JS?

Я пытаюсь создать функцию, которая принимает массив и функцию обратного вызова. Функция должна возвращать истину, если все значения в массиве, переданном в обратный вызов, возвращают истину, в противном случае - ложь. Но я не уверен, что делаю неправильно

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
});

ожидаемые результаты => ложь но я становлюсь правдой.

Возврат внутри обратного вызова к методу forEach вызывает совершенно ничего в функции, в которой был вызван этот метод. Я бы предложил отфильтровать массив и проверить полученную длину. В качестве альтернативы, более новые версии JavaScript фактически имеют каждый метод для массивов: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

jonrsharpe 05.01.2019 00:37

Это только я, или обратный вызов передается неверно синтаксически? {} в конце выглядит странно

Taplar 05.01.2019 00:41
Array.prototype имеет every, который делает то, что вы хотите, например [1, 2, 3, 4, 5].every(val => val < 2)
ic3b3rg 05.01.2019 00:48

@ ic3b3rg Он явно пытается понять, как самому реализовать подобную функцию.

Barmar 05.01.2019 00:57

@Barmar Не уверен, что он знает о Array.prototype.every

ic3b3rg 05.01.2019 00:58

Я предполагаю, что это академическое упражнение, так что это не имеет значения.

Barmar 05.01.2019 01:01
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
6
61
4

Ответы 4

Вы можете использовать для этого 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

Taplar 05.01.2019 00:56

Возврат 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 даст вам такое же преимущество в производительности.

Это полезно знать. Мне было интересно, почему цикл продолжает повторяться даже после выполнения условия. Спасибо за это!

user3166915 05.01.2019 16:33
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}));

Другие вопросы по теме