Привет Хабр! Предлагаю вам статьи Rethinking JavaScript: Replace break by going functional.  В моей предыдущей статье Rethinking JavaScript: Death of the For Loop (есть перевод: Переосмысление JavaScript: Смерть for) я пытался убедить вас отказаться от for в пользу функционального подхода. И вы задали хороший вопрос "Что на счет break?". break это GOTO циклов и его следует избегать Нам следует отказаться от break также, как мы когда-то отказались от GOTO. Вы можете думать, "Да ладно, Джо, ты преувеличиваешь. Как это break это GOTO?" Рассмотрим метки (прим. labels) для доказательства утверждения. В других языках метки работают в паре с GOTO. В JavaScript'e же метки работают вместе с break и continue, что сближает последних с GOTO. JavaScript'вые метка, break и continue это пережиток GOTO и неструктурированного программирования  "Но break никому не мешает, почему бы не оставить возможность его использовать?" Это может звучать нелогично, но ограничения это хорошая вещь. Запрет GOTO прекрасный тому пример. Мы также с удовольствием ограничиваем себя директивой "use strict", а иногда даже осуждаем игнорирующих её. "Ограничения могут сделать вещи лучше. Намного лучше" — Чарльз Скалфани Ограничения заставляют нас писать лучше. Why Programmers Need Limits Я не буду врать. Не существует простого и быстрого способа заменить break. Здесь нужен совершенно иной стиль программирования. Совершенно иной стиль мышления. Функциональный стиль мышления. Хорошая новость в том, что существует много библиотек и инструментов, которые могут нам помочь, такие как Lodash, Ramda, lazy.js, рекурсия и другие. Например, у нас есть коллекция котов и функция isKitten: Начнем со старого доброго цикла for. Мы проитерируем наших котов и выйдем из цикла, когда найдем первого котенка. Сравним с аналогичным lodash вариантом Этот был довольно простой пример, давайте попробуем что-нибудь по-серьезнее. Будем перебирать наших котов пока не найдем 5 котят. Прим. переводчика: позволил себе немного вольности и дополнил размышления о легком пути недостающими, по моему мнению, частями. Мы можем использовать стандартные методы массива JavaScript. Но это не очень функционально. Мы можем воспользоваться Lodash'ем. Это достаточно хорошее решение пока вы ищете котят в небольшой коллекции котов. Lodash великолепен и умеет делать массу хороших вещей, но сейчас нам нужно что-то более специфичное. Тут нам поможет lazy.js. Он "Как underscore, но ленивый". Его ленивость нам и нужна. Дело в том, что ленивые последовательности (которые предоставляет lazy.js) сделают ровно столько преобразований (filter, map и тд) сколько элементов вы хотите получить в конце. Библиотеки это весело, но иногда по настоящему весело сделать что-то самому! Как на счет того, чтобы создать обобщенную (прим. generic) функцию, которая будет работать как filter, но вдобавок будет уметь останавливаться при нахождении определенного количества элементов? Сначала обернем наш старый добрый цикл в функцию. Теперь давайте обобщим функцию и вынесем всё котоспецифичное. Заменим 5 на limit, isKitten на predicate и cats на list и вынесем их в параметры функции. В итоге у нас получилась готовая для повторного использования функция takeFirst, которая полностью отделена от нашей кошачьей бизнес логики! takeFirst — чистая функция. Результат ее выполнения определяется только входными параметрами. Функция гарантированно вернет тот же результат получив те же параметры. Функция до сих пор содержит противный for, так что продолжим рефакторинг. Следующим шагом переместим i и newList в параметры функции. Мы хотим закончить рекурсию (isDone) когда limit достигнет 0 (limit будет уменьшаться во время рекурсии) или когда закончится list. Если мы не закончили, мы выполняем predicate. Если результат predicate истинен, мы вызываем takeFirst, уменьшаем limit и присоединяем элемент к newList.
Иначе берем следующий элемент списка. Последний наш шаг замены if на тернарный оператор объяснен в моей статье Rethinking Javascript: the If Statement. Теперь вызовем наш новый метод: Чтобы сделать takeFirst ещё полезнее мы могли бы её каррировать (прим. currying) и использовать для создания других функций. (больше о карировании в другой статье) Есть много хороших библиотек (например lodash, ramda, lazy.js), но будучи достаточно смелыми, мы можем воспользоваться силой рекурсии чтобы создавать собственные решения! Я должен предупредить, что хотя takeFirst невероятно крутая, с рекурсией приходит великая сила, но также и большая ответственность. Рекурсия в мире JavaScript может быть очень опасной и легко привести к ошибке переполнения стека Maximum call stack size exceeded. Я расскажу о рекурсии в JavaScript в следующей статьей.  Я знаю что это мелочь, но меня очень радует когда кто-то подписывается на меня на Медиуме и Твиттере @joelnet. Если же вы думаете что я дурак, скажите это мне в комментах ниже. → Functional JavaScript: Functional Composition For Every Day Use.
→ Rethinking JavaScript: Death of the For Loop
(есть перевод: Переосмысление JavaScript: Смерть for)
→ Rethinking JavaScript: Elliminate the switch statement for better code
→ Functional JavaScript: Resolving Promises Sequentially Прим. переводчика: выражаю благодарность Глебу Фокину и Богдану Добровольскому в написании перевода, а также Джо Томсу, без которого перевод был бы невозможен. JavaScript разработчик