<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Daniil Zaozersky</title><author><name>Daniil Zaozersky</name></author><id>https://teletype.in/atom/js_by_vladilen</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/js_by_vladilen?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@js_by_vladilen?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=js_by_vladilen"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/js_by_vladilen?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-10-23T23:51:43.570Z</updated><entry><id>js_by_vladilen:uCf6llE1J</id><link rel="alternate" type="text/html" href="https://teletype.in/@js_by_vladilen/uCf6llE1J?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=js_by_vladilen"></link><title>Краткое введение в pipe () и compose () в JavaScript</title><published>2021-04-12T12:14:32.133Z</published><updated>2021-04-12T12:41:34.448Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/4e/9e/4e9e7ecb-efe7-43a4-8b3a-a2ff8d65a25c.jpeg"></media:thumbnail><summary type="html">&lt;img src=&quot;https://teletype.in/files/49/dc/49dc1c3f-fe53-4e92-9b93-1d61c102dfe6.jpeg&quot;&gt;Концепция pipe проста - сочетание n функций в себе. Это конвейер, идущий слева на право, вызывающий каждую функцию с выводом последней. </summary><content type="html">
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/49/dc/49dc1c3f-fe53-4e92-9b93-1d61c102dfe6.jpeg&quot; width=&quot;1399&quot; /&gt;
    &lt;figcaption&gt;Abstract вектор создан(а) macrovector - &lt;a href=&quot;https://vk.com/away.php?utf=1&amp;to=http%3A%2F%2Fru.freepik.com&quot; target=&quot;_blank&quot;&gt;ru.freepik.com&lt;/a&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h2&gt;Pipe&lt;/h2&gt;
  &lt;p&gt;Концепция &lt;code&gt;pipe &lt;/code&gt;проста - сочетание &lt;code&gt;n&lt;/code&gt; функций в себе. Это конвейер, идущий слева на право, вызывающий каждую функцию с выводом последней. &lt;/p&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;Напишем функцию, которая возвращает чей-то &lt;code&gt;name&lt;/code&gt;.&lt;/p&gt;
  &lt;pre data-lang=&quot;javascript&quot;&gt;getName = (person) =&amp;gt; person.name;

getName({ name: &amp;#x27;Buckethead&amp;#x27; });
// &amp;#x27;Buckethead&amp;#x27;&lt;/pre&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;Напишем функцию, которая переводит строки в верхний регистр.&lt;/p&gt;
  &lt;pre data-lang=&quot;javascript&quot;&gt;uppercase = (string) =&amp;gt; string.toUpperCase();

uppercase(&amp;#x27;Buckethead&amp;#x27;);
// &amp;#x27;BUCKETHEAD&amp;#x27;
&lt;/pre&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;Итак, если бы мы хотели получить имя &lt;code&gt;person&lt;/code&gt; в верхнем регистре , мы могли  бы написать так:&lt;/p&gt;
  &lt;pre data-lang=&quot;javascript&quot;&gt;name = getName({ name: &amp;#x27;Buckethead&amp;#x27; });
uppercase(name);

// &amp;#x27;BUCKETHEAD&amp;#x27;&lt;/pre&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;Мы можем сократить это действие, исключив промежуточную переменную &lt;code&gt;name&lt;/code&gt;.&lt;/p&gt;
  &lt;pre data-lang=&quot;javascript&quot;&gt;uppercase(getName({ name: &amp;#x27;Buckethead&amp;#x27; }));&lt;/pre&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;Уже лучше, но вложения могут стать слишком глубокими и с этим будет не удобно работать. Что, если мы хотим добавить функцию, которая получает первые 6 символов строки?&lt;/p&gt;
  &lt;pre data-lang=&quot;javascript&quot;&gt;get6Characters = (string) =&amp;gt; string.substring(0, 6);

get6Characters(&amp;#x27;Buckethead&amp;#x27;);
// &amp;#x27;Bucket&amp;#x27;&lt;/pre&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;В результате чего:&lt;/p&gt;
  &lt;pre data-lang=&quot;javascript&quot;&gt;get6Characters(uppercase(getName({ name: &amp;#x27;Buckethead&amp;#x27; })));

// &amp;#x27;BUCKET&amp;#x27;;&lt;/pre&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;Давайте сойдемся с ума и добавим ещё функцию для переворота строк.&lt;/p&gt;
  &lt;pre data-lang=&quot;javascript&quot;&gt;reverse = (string) =&amp;gt;
  string
    .split(&amp;#x27;&amp;#x27;)
    .reverse()
    .join(&amp;#x27;&amp;#x27;);

reverse(&amp;#x27;Buckethead&amp;#x27;);
// &amp;#x27;daehtekcuB&amp;#x27;&lt;/pre&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;Теперь у нас есть:&lt;/p&gt;
  &lt;pre data-lang=&quot;javascript&quot;&gt;reverse(get6Characters(uppercase(getName({ name: &amp;#x27;Buckethead&amp;#x27; }))));
// &amp;#x27;TEKCUB&amp;#x27;&lt;/pre&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;Это выглядит немного громоздким...&lt;/p&gt;
  &lt;h2&gt;Pipe на помощь!&lt;/h2&gt;
  &lt;p&gt;Вместо того, чтобы вклинивать функции внутри функций или создавать кучу промежуточных переменных, давайте используем &lt;code&gt;pipe&lt;/code&gt; и всё!&lt;/p&gt;
  &lt;pre data-lang=&quot;javascript&quot;&gt;pipe(
  getName,
  uppercase,
  get6Characters,
  reverse
)({ name: &amp;#x27;Buckethead&amp;#x27; });
// &amp;#x27;TEKCUB&amp;#x27;&lt;/pre&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;Чистое искусство. Это как список дел! &lt;/p&gt;
  &lt;p&gt;Давайте разберём.&lt;/p&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;Для демонстрационных целей, будем использовать &lt;code&gt;pipe&lt;/code&gt;реализацию из&lt;a href=&quot;https://medium.com/javascript-scene/reduce-composing-software-fe22f0c39a1d&quot; target=&quot;_blank&quot;&gt; одной статьи Эрика Эллиотта&lt;/a&gt;.&lt;/p&gt;
  &lt;pre data-lang=&quot;javascript&quot;&gt;pipe = (...fns) =&amp;gt; (x) =&amp;gt; fns.reduce((v, f) =&amp;gt; f(v), x);&lt;/pre&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;Мы можем передавать &lt;code&gt;n&lt;/code&gt; функции по конвейеру. Каждая функция берет результат предыдущей, и всё это сводится к единственному значению.&lt;/p&gt;
  &lt;p&gt;Передав, написанные ранее, функции, мы  можем использовать &lt;code&gt;pipe&lt;/code&gt;, как это сделали выше:&lt;/p&gt;
  &lt;pre data-lang=&quot;javascript&quot;&gt;pipe(
  getName,
  uppercase,
  get6Characters,
  reverse
)({ name: &amp;#x27;Buckethead&amp;#x27; });
// &amp;#x27;TEKCUB&amp;#x27;&lt;/pre&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;Для пошаговой демонстрации добавим несколько отладчиков и пройдём строка за строкой. &lt;/p&gt;
  &lt;pre data-lang=&quot;javascript&quot;&gt;pipe = (...functions) =&amp;gt; (value) =&amp;gt; {
  debugger;

  return functions.reduce((currentValue, currentFunction) =&amp;gt; {
    debugger;

    return currentFunction(currentValue);
  }, value);
};&lt;/pre&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/ab/00/ab0024a1-c7be-4636-ac15-d920fadbd67b.png&quot; width=&quot;793&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;Вызовите &lt;code&gt;pipe&lt;/code&gt; с нашими наработками и начнутся чудеса.&lt;/p&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/b7/cd/b7cda3d3-71fd-4f5b-adfe-ac0e50d03617.png&quot; width=&quot;1002&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;Проверим локальные переменные. &lt;code&gt;functions&lt;/code&gt;представляет собой массив из 4 функций, а &lt;code&gt;value&lt;/code&gt; и есть &lt;code&gt;{ name: &amp;#x27;Buckethead&amp;#x27; }&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Помимо наших параметров в &lt;code&gt;pipe&lt;/code&gt; можно использовать любое количество функций. Он просто зациклится и будет вызывать каждую из них.&lt;/p&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/15/87/15877ca4-020f-4d2f-851f-3915ba95d05c.png&quot; width=&quot;772&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;В следующем отладчике мы внутри &lt;code&gt;reduce&lt;/code&gt;. Здесь &lt;code&gt;currentValue&lt;/code&gt;передается &lt;code&gt;currentFunction&lt;/code&gt;и возвращается.&lt;/p&gt;
  &lt;p&gt;Мы видим результат &lt;code&gt;&amp;#x27;Buckethead&amp;#x27;&lt;/code&gt;потому, что &lt;code&gt;currentFunction&lt;/code&gt;возвращает &lt;code&gt;.name&lt;/code&gt;свойство любого объекта. На данном этапе будет возвращен &lt;code&gt;reduce&lt;/code&gt;, а на следующем &lt;code&gt;currentValue&lt;/code&gt; уже станет новым . Давайте перейдем к следующему отладчику и посмотрим.&lt;/p&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/3d/97/3d977e9d-bd6a-49d9-b9d9-a4629f074043.png&quot; width=&quot;771&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;Теперь &lt;code&gt;currentValue&lt;/code&gt;это , &lt;code&gt;‘Buckethead’&lt;/code&gt;потому что это то , что нам вернула предыдущая функция. Сейчас &lt;code&gt;currentFunction &lt;/code&gt;это &lt;code&gt;uppercase&lt;/code&gt;, поэтому&lt;code&gt;&amp;#x27;BUCKETHEAD&amp;#x27;&lt;/code&gt;будет в следующем &lt;code&gt;currentValue&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/80/35/8035f44c-e185-4aaf-9546-d9b64e1c040a.png&quot; width=&quot;771&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;По тому же сценарию из&lt;code&gt; ‘BUCKETHEAD’ &lt;/code&gt;возьмутся первые 6 символов и передадутся следующей функции.&lt;/p&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/61/47/614745a6-334e-4f3d-af73-b8294860c363.png&quot; width=&quot;767&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;reverse(‘.aedi emaS’)&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/dc/1e/dc1edbec-d298-499f-a892-e12b7932e4da.png&quot; width=&quot;829&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;Ура мы это сделали!&lt;/p&gt;
  &lt;h2&gt;А что на счёт compose()?&lt;/h2&gt;
  &lt;p&gt;Это тот же &lt;code&gt;pipe&lt;/code&gt;, просто, в другом направлении.&lt;/p&gt;
  &lt;p&gt;Поэтому, если вы хотите получить тот же результат, что и с помощью нашего &lt;code&gt;pipe&lt;/code&gt;выше, необходимо произвести все те же действия, но наоборот.&lt;/p&gt;
  &lt;pre data-lang=&quot;javascript&quot;&gt;compose(
  reverse,
  get6Characters,
  uppercase,
  getName
)({ name: &amp;#x27;Buckethead&amp;#x27; });&lt;/pre&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;Обратите внимание, что&lt;code&gt;getName&lt;/code&gt; уже последний в цепочке, а &lt;code&gt;reverse&lt;/code&gt;первый.&lt;/p&gt;
  &lt;p&gt;Вот быстрая реализация &lt;code&gt;compose&lt;/code&gt;, снова любезно предоставленная &lt;a href=&quot;https://medium.com/javascript-scene/reduce-composing-software-fe22f0c39a1d&quot; target=&quot;_blank&quot;&gt;Эриком Элиоттом из той же статьи&lt;/a&gt;.&lt;/p&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;Перевод &lt;a href=&quot;https://www.freecodecamp.org/news/pipe-and-compose-in-javascript-5b04004ac937/&quot; target=&quot;_blank&quot;&gt;статьи&lt;/a&gt; Язида Бзадоу.&lt;/p&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;hr /&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;Если вы хотите ещё больше познавательного контента из мира Java Script, присоединитесь к Telegram каналу &lt;a href=&quot;https://t.me/js_by_vladilen&quot; target=&quot;_blank&quot;&gt;@js_by_vladilen&lt;/a&gt;.&lt;/p&gt;

</content></entry></feed>