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

function each(collection, callback) {
  var arr = [];
  for(var i = 0; i < collection.length; i++) {
      var result = callback(collection[i])
      if (typeof result !== 'undefined') {
        arr.push(callback(collection[i]));
      }
    }
  return arr
}

function isNumber(item) {
    if (typeof item === "number") {
      return item * 2;
    }
}

Я пытаюсь понять функции высшего порядка. Вышеупомянутое работает, но, по-видимому, не рекомендуется возвращать значение с isNumber. Мне сказали, что должно быть возвращено логическое значение. Почему? Оно работает.

Обновление: похоже, это из-за названия функции! Спасибо всем, я просто подумал, что может быть какая-то техническая причина


person mattnewbie    schedule 16.06.2016    source источник
comment
Откуда взялось это предупреждение?   -  person Juan Mendes    schedule 16.06.2016
comment
Насколько я могу судить, это всего лишь случай твоего имени. isNumber почти как вопрос, где ответ будет да/нет или boolean. Ваш код будет выглядеть примерно так: isNumber(5) == 10, что просто читается неправильно. Я также вообще не вижу актуальности функции each в контексте этого вопроса.   -  person Hopeful Llama    schedule 16.06.2016
comment
@JuanMendes Мне лично не сказали (просто поместите это для упрощения). В этом примере здесь stackoverflow.com/questions/31169722/ . Спасибо!   -  person mattnewbie    schedule 16.06.2016
comment
Функции, начинающиеся с is, всегда будут содержать ожидание логического результата, который либо есть, либо не является.   -  person Alex K.    schedule 16.06.2016
comment
Почему функция с именем isNumber(item) должна удваивать число? Не должна ли функция, удваивающая число, называться doubleNumber или multiplyNumberByTwo или как-то иначе, что не удивило бы другого программиста?   -  person Ghost    schedule 16.06.2016
comment
С какой стати ты звонишь бедняге дважды. У вас уже есть результат, присвоенный result.   -  person Redu    schedule 16.06.2016


Ответы (1)


Если функция называется isNumber, она должна возвращать логическое значение.

Кроме того, каждая ваша функция является map, а не each. В этом случае ваш код, вероятно, должен выглядеть так.

function flatMap(collection, callback) {
  var arr = [];
  for(var i = 0; i < collection.length; i++) {
      var result = callback(collection[i])
      if (typeof result !== 'undefined') {
        arr.push(callback(collection[i]));
      }
    }
  return arr;
}

function times2(item) {
    if (typeof item === "number") {
      return item * 2;
    }
    return item;
}

map([1,2,3,"hello"], times2);

Если вам нужна итерация, которую можно остановить, то это будет выглядеть так:

function iterate(collection, callback) {
  for(var i = 0; i < collection.length; i++) {
    var result = callback(collection[i])
    if (typeof result === false) {
      return;
    }
  }
}

function doSomethingAndStopIfNotANumber(item) {
   console.log(item);
   return typeof item == "number";
}

iterate([1,2,3, "hello", 4, 5], doSomethingAndStopIfNotANumber);

Обратите внимание, что Array.prototype.forEach не позволяет чтобы остановить итерацию, вернув false, для этого вам нужно неправильно использовать Array.prototype.every (потому что эта функция возвращает логическое значение, так что это просто семантическая проблема, а не карта, где вы создаете массив и выбрасываете его) или напишите функцию, как я сделал выше.

person Juan Mendes    schedule 16.06.2016
comment
В чем разница между каждым и картой? - person tpdietz; 16.06.2016
comment
Спасибо . Я думал, что ответ будет сложнее! Это не мой код, я нашел его на этом сайте в другом вопросе, я пытаюсь понять функции высшего порядка и хотел уточнить этот момент. Спасибо за ваше время! stackoverflow.com/questions/31169722/ - person mattnewbie; 16.06.2016
comment
FWIW, поскольку ваша функция map будет отправлять результат обратного вызова только в том случае, если он определен, я бы сказал, что вместо этого он больше похож на flatMap. Я думаю, что важным инвариантом является то, что map сохраняет размер коллекции. - person Andrzej Doyle; 16.06.2016
comment
map используется, когда вы хотите преобразовать каждый элемент массива и вернуть новый массив. each — это когда вы просто хотите что-то сделать с каждым элементом, но не хотите создавать новый массив с сопоставленным результатом. Использование map, когда вы имеете в виду each, означает, что массив будет создан, изменен и затем выброшен. - person Juan Mendes; 16.06.2016