Одна из замечательных особенностей метода filter() для массивов JavaScript заключается в том, что он возвращает новый массив на основе условия фильтрации, которое вы задаете в своем обратном вызове. Под капотом ваша функция обратного вызова проверяется на истинное значение, и если она проходит успешно, filter() создает новый массив для возврата вам. Базовая реализация может выглядеть так:

function myBasicFilter(array, callback){
  var newArray = [];
  for (var i = 0; i < array.length; i++){
    if (callback(array[i])){
      newArray.push(array[i]);
    }
  }
  return newArray;
}

и мы можем использовать его так:

var coffeeStuffs = ['coffee dirt', 'water', 'coffee machine', 'coffee'];
var filderedCoffee = myBasicFilter(coffeeStuffs, function(item){
  return item === 'coffee';
}); // ['coffee']

Интересным следствием является то, что вы можете вообще опустить проверку if — поскольку filter() заботится только о истинных значениях, возвращаемых вашим обратным вызовом, вы возвращаете нужные значения в новом массиве. Это очень удобно при работе с данными, поступающими с сервера, где у вас может быть список объектов, которые вы хотите отфильтровать:

// pretend data from some server...
const coffeeData = [{
  name: "Arusha",
  species: "C. arabica",
  region: "Mount Meru in Tanzania, and Papua New Guinea",
  comments: "either a Typica variety or a French Mission."
},{
  name: "Bergendal, Sidikalang",
  species:  "C. arabica",
  region: "Indonesia",
  comments: "Both are Typica varieties which survived the..."
},{
  name: "Catimor",
  species: "Interspecific hybrid",
  region: "Latin America, Indonesia, India",
  comments: "This is cross between Timor coffee and Caturra coffee..."
},{
  name: "Bourbon",
  species: "C. arabica",
  region: "Réunion, Rwanda, Latin America.",
  comments: "Around 1708 the French planted coffee ..."
}];
// using arrow func for brevity
const arabicaSpecies = 
  coffeeData.filter(item => item.species === 'C. arabica');
// ... do some more stuff 

arabicaSpecies будет представлять собой массив объектов, где виды равны тому, что нас интересует, в данном случае это что-то со значением «C. арабика». Мы ничего не потеряем при переводе в том, что касается содержимого объектов данных — только объекты, которые не совпадают. Мы можем сделать это инклюзивным или эксклюзивным, изменив === на !== в нашей проверке сравнения.

Важно отметить, что встроенный filter() передает вашему обратному вызову еще пару вещей, а именно индекс и исходный массив, если они вам нужны. У Mozilla есть замечательная документация по такого рода вещам: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter — в качестве бонуса они также показывают полифилл это написано по спецификации и делает гораздо больше, чем простой пример выше!

array.filter() — отличный инструмент — вам следует сделать следующие на array.map() и array.reduce()!

Удачного JavaScript!