{"componentChunkName":"component---src-templates-post-js","path":"/javascript/ponimaem-carrirovanie-v-javascript/","result":{"pageContext":{"slug":"ponimaem-carrirovanie-v-javascript","content":"\n<p>В этой статье вы простым языком поймете работу с каррированием в JavaScript и увидите рабочие примеры его применения.</p>\n\n\n\n<p class=\"author\"><a href=\"https://blog.bitsrc.io/understanding-currying-in-javascript-ceb2188c339\"><em>Перевод статьи Understanding&nbsp;Currying&nbsp;in JavaScript</em></a></p>\n\n\n\n<p id=\"b4e4\">Функциональное программирование это стиль написания кода, в котором функции передают как аргументы (колбэки) и отдают тоже функции без сайд-эффектов(изменения состояния приложения).</p>\n\n\n\n<p id=\"d01f\">Множество языков приняли такую стилистику в своей работе с кодом. Самые популярные из них это: JavaScript, Haskell, Clojure, Erlang и Scala.</p>\n\n\n\n<p id=\"4ab5\">Возможность передавать и возвращать функции породила много других концепций:</p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>Чистые функции</p><p>Каррирование</p><p>Функции высшего порядка</p></blockquote>\n\n\n\n<p>И сейчас&nbsp;мы разберем одну из них. А именно каррирование, ну или карринг. Кому как удобно.</p>\n\n\n\n<h2 id=\"23c2\"><strong>Что такое каррирование?</strong></h2>\n\n\n\n<p id=\"e854\">Это процесс в функциональном программировании при котором мы можем трансформировать функцию с несколькими аргументами в упорядоченную последовательность вложенных друг в друга совершенно разных функций. Она возвращает новую функцию, которая ожидает уже следующий аргумент.</p>\n\n\n\n<p id=\"6171\">Она будет отдавать новую функцию до тех пор, пока не закончится количество аргументов. Аргументы остаются доступными в области видимости и используются при запуске кода, когда завершающая функция в цепочке каррирования отдаётся и запускается.</p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>Каррирование это процесс превращения функции с множественной арностью в функцию с меньшей арностью — Кристина Брэйнвэйв.</p></blockquote>\n\n\n\n<p>Обратите внимание, что термин арность относится напрямую к количеству аргументов которое берет функция. Для примера:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>function fn(a, b) {\n    //...\n}function _fn(a, b, c) {\n    //...\n}</code></pre>\n\n\n\n<p id=\"e7a1\">У функции&nbsp;<code>fn</code>&nbsp;два аргумента (2х арная функция), а&nbsp;<code>_fn</code>&nbsp;имеет три аргумента(3х арная функция).</p>\n\n\n\n<p id=\"3046\">Так что каррирование трансформирует функцию с несколькими аргументами в последовательную серию связанных функций, каждая из которых берет один из нужных аргументов.</p>\n\n\n\n<p id=\"b990\">Давайте посмотрим на простой пример:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>function multiply(a, b, c) {\n    return a * b * c;\n}</code></pre>\n\n\n\n<p>Функция берёт три аргумента, умножает числа и отдаёт результат:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>multiply(1,2,3); // 6</code></pre>\n\n\n\n<p>Посмотрите как мы вызвали функцию умножения с полным набором аргументов. Теперь давайте создадим каррированную версию этой функции и посмотрим, как бы мы могли вызвать ту же функцию, но уже через серию запросов:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>function multiply(a) {\n    return (b) => {\n        return (c) => {\n            return a * b * c\n        }\n    }\n}log(multiply(1)(2)(3)) // 6</code></pre>\n\n\n\n<p id=\"7563\">Мы превратили функцию&nbsp;<code>multiply(1,2,3)</code>&nbsp;в несколько вызовов других вызовов&nbsp;<code>multiply(1)(2)(3)</code>.</p>\n\n\n\n<p id=\"d8bd\">Просто напросто одна простая функция была переделана в серию последовательных функций. Чтобы получить результат умножения трёх чисел&nbsp;<em>1, 2 и 3</em>, числа передаются одно за другим, каждое число передаётся следующей функции для запуска.</p>\n\n\n\n<p id=\"e5db\">Мы могли бы разделить&nbsp;<code>multiply(1)(2)(3)</code>&nbsp;на несколько функций, чтобы вы лучше поняли процесс:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>const mul1 = multiply(1);\nconst mul2 = mul1(2);\nconst result = mul2(3);\nlog(result); // 6</code></pre>\n\n\n\n<p>Давайте рассмотрим всё по последовательности. Мы передали&nbsp;<code>1</code>&nbsp;функции&nbsp;<code>multiply</code>:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>let mul1 = multiply(1);</code></pre>\n\n\n\n<p>Она отдаёт функцию:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>return (b) => {\n        return (c) => {\n            return a * b * c\n        }\n   }</code></pre>\n\n\n\n<p>Теперь&nbsp;<code>mul1</code>&nbsp;это функция с аргументом&nbsp;<code>b</code>.</p>\n\n\n\n<p>Далее мы берём функцию&nbsp;<code>mul1</code>, передавая ей&nbsp;<code>2</code>:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>let mul2 = mul1(2);</code></pre>\n\n\n\n<p><code>mul1</code> отдаст третью функцию:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>return (c) => {\n            return a * b * c\n        }</code></pre>\n\n\n\n<p id=\"0a44\">Отданная функция теперь хранится в переменной&nbsp;<code>mul2</code>.</p>\n\n\n\n<p id=\"13cf\">По-сути&nbsp;<code>mul2</code>&nbsp;будет:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>mul2 = (c) => {\n            return a * b * c\n    }</code></pre>\n\n\n\n<p>Где&nbsp;<code>mul2</code>&nbsp;вызывается с&nbsp;<code>3</code>&nbsp;как параметром:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>const result = mul2(3);</code></pre>\n\n\n\n<p>Что делает вычисления вместе с параметрами, переданными ранее:&nbsp;<code>a=1</code>,&nbsp;<code>b=2</code>. В итоге получаем&nbsp;<code>6</code>.</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>log(result); // 6</code></pre>\n\n\n\n<p id=\"0974\">Будучи вложенной функцией,&nbsp;<code>mul2</code>&nbsp;имеет доступ к области видимости других функций,&nbsp;<code>multiply</code>&nbsp;и&nbsp;<code>mul1</code>.</p>\n\n\n\n<p id=\"4524\">Вот так&nbsp;<code>mul2</code>&nbsp;будет делать вычисления с переменными указанными в фунциях из которых уже вышли. Хоть функции уже давно и были отданы и зачищены в памяти, но переменные из них ещё остаются доступными.</p>\n\n\n\n<p id=\"ac9e\">Вы видите, что три числа были применены одна за другой каждый раз и каждый раз новая функция отдавалась, но до тех пор, пока все числа не иссякнут.</p>\n\n\n\n<p id=\"1ff5\">Давайте посмотрим на другой пример:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>function volume(l,w,h) {\n    return l * w * h;\n}\nconst aCylinder = volume(100,20,90) // 180000l</code></pre>\n\n\n\n<p id=\"b333\">У нас есть функция&nbsp;<code>volume</code>, которая высчитывает объем любой твёрдой формы.</p>\n\n\n\n<p id=\"368b\">Подход с каррированием будет принимать один аргумент и отдавать функцию, которая также будет принимать ещё один аргумент и отдавать тоже функцию. Это будет продолжаться до последнего аргумента и пока не вернется последняя функция, в которой произойдут уже все операции с умножением предыдущих аргументов вместе с последним.</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>function volume(l) {\n    return (w) => {\n        return (h) => {\n            return l * w * h\n        }\n    }\n}\nconst aCylinder = volume(100)(20)(90) // 180000</code></pre>\n\n\n\n<p>Тоже, что и в функции&nbsp;<code>multiply</code>, последняя функция принимает только&nbsp;<code>h</code>, но произведет операции с другими переменными, которые были в уже завершившихся функциях. Это работает вне зависимости от&nbsp;замыканий.</p>\n\n\n\n<p>В общем, суть каррирования в том, что мы берём функцию и извлекаем другую функцию, которая отдаёт уже специализированную функцию.</p>\n\n\n\n<h1 id=\"5ddb\"><strong>Каррирование в математике</strong></h1>\n\n\n\n<p id=\"6a9e\">Мне нравится математическая иллюстрация на&nbsp;<a href=\"https://ru.wikipedia.org/wiki/%D0%9A%D0%B0%D1%80%D1%80%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5\">Википедии</a>, показывающая концепцию каррирования. Давайте посмотрим на неё с нашим собственными примером.</p>\n\n\n\n<p id=\"2814\">У нас есть уравнение.</p>\n\n\n\n<pre class=\"wp-block-code\"><code>f(x,y) = x^2 + y = z</code></pre>\n\n\n\n<p id=\"167a\">Есть две переменные x и y. Если бы двум переменным было&nbsp;выдано&nbsp;<code>x=3</code>&nbsp;и&nbsp;<code>y=4</code>, то каким было бы&nbsp;<code>z</code>.</p>\n\n\n\n<p id=\"4d50\">Если мы заменим y на 4 и x на 3 в&nbsp;<code>f(x,y)</code>:</p>\n\n\n\n<pre class=\"wp-block-code\"><code>f(x,y) = f(3,4) = x^2 + y = 3^2 + 4 = 13 = z</code></pre>\n\n\n\n<p id=\"2653\">То мы получим результат —&nbsp;<code>13</code>.</p>\n\n\n\n<p id=\"ca75\">Мы можем каррировать <code>f(x,y)</code>, чтобы получить переменные из последовательности функций:</p>\n\n\n\n<pre class=\"wp-block-code\"><code>h = x^2 + y = f(x,y)\nhy(x) = x^2 + y = hx(y) = x^2 + y\n&#91;hx => w.r.t x] and &#91;hy => w.r.t y]</code></pre>\n\n\n\n<p id=\"d307\">Если мы поправим&nbsp;<code>x=3</code>&nbsp;в уравнении&nbsp;<code>hx(y) = x² + y</code>, то оно отдаст новое уравнение у которого есть y как переменная:</p>\n\n\n\n<p id=\"74d2\">h3(y) = 3² + y = 9 + y</p>\n\n\n\n<p id=\"4889\">Это тоже самое, что и:</p>\n\n\n\n<pre class=\"wp-block-code\"><code>h3(y) = 3^2 + y = 9 + y</code></pre>\n\n\n\n<p id=\"c54d\">Значение не было решено, оно отдало новое уравнение&nbsp;<code>9 + y</code>, ожидая ещё одну переменную&nbsp;<code>y</code>.</p>\n\n\n\n<p id=\"a9e0\">Далее мы передадим&nbsp;<code>y=4</code>:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>h3(4) = h(3)(4) = f(3,4) = 9 + 4 = 13</code></pre>\n\n\n\n<p id=\"bb5f\"><code>y</code>&nbsp;это последняя переменная в цепочке, сложение происходит с предыдущей переменной&nbsp;<code>x=3</code>&nbsp;и получается 13.</p>\n\n\n\n<p id=\"d1c4\">Мы просто напросто каррировали уравнение<code>&nbsp;f(x,y) = 3² + y</code>&nbsp;в последовательность других уравнений.</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>h3(y) = h(3)(y) = f(3,y) = 3^2 + y = 9 + y</code></pre>\n\n\n\n<p id=\"549d\">Перед тем как получить результат.</p>\n\n\n\n<p id=\"b44b\">Тут немного математики и вы можете не совсем понять, что там происходит. Почитайте все детали на Википедии.</p>\n\n\n\n<h2 id=\"ace0\">Каррирование и частичное применение функций</h2>\n\n\n\n<p id=\"2368\">Сейчас некоторые могут подумать, что количество вложенных функций в карированной функции зависит от числа получаемых аргументов. Ну, собственно в карировании так оно и есть.</p>\n\n\n\n<p id=\"bad3\">Сейчас я могу сделать функцию&nbsp;<code>volume</code>&nbsp;таким образом:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>function volume(l) {\n    return (w, h) => {\n        return l * w * h\n    }\n}</code></pre>\n\n\n\n<p>И теперь её можно вызывать так:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>const hCy = volume(70);\nhCy(203,142);\nhCy(220,122);\nhCy(120,123);</code></pre>\n\n\n\n<p>Или вот так:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>volume(70)(90,30);\nvolume(70)(390,320);\nvolume(70)(940,340);</code></pre>\n\n\n\n<p id=\"9a86\">Мы только что сделали специальную функцию, которая считает объем любого цилиндрического объекта длинной (<code>l</code>), 70.</p>\n\n\n\n<p id=\"c137\">Она принимает 3 аргумента и имеет 2 вложенные функции в отличие от предыдущей версии, которой нужно 3 аргумента и у которой 3 вложенные функции.</p>\n\n\n\n<p id=\"7eb3\">Но эта версия без каррирования. Там мы просто сделали частичное применение функции&nbsp;<code>volume</code>.</p>\n\n\n\n<p id=\"7bca\">Собственно каррирование и частичное применение схожи, но подразумевают под собой разные концепции.</p>\n\n\n\n<p id=\"244a\">Частичное применение преобразует функцию в другую функцию с меньшей арностью.</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>function acidityRatio(x, y, z) {\n    return performOp(x,y,z)\n}\n|\nV\nfunction acidityRatio(x) {\n    return (y,z) => {\n        return performOp(x,y,z)\n    }\n}</code></pre>\n\n\n\n<p id=\"a686\">Обратите внимание, что тут я оставил в покое детали выполнения функции&nbsp;<code>peroformOp</code>. Она не очень важна. Всё, что вам нужно знать, это концепции применения каррирования и частичного применения.</p>\n\n\n\n<p id=\"56d3\">Это частичное применение функции&nbsp;<code>acidityRatio</code>. Тут нет каррирования. Эта функция частично применена, чтобы получить меньшую арность, ожидая меньшее количество аргументов, чем изначальная функция.</p>\n\n\n\n<p id=\"c978\">Чтобы применить каррирование, мы могли бы сделать так:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>function acidityRatio(x) {\n    return (y) = > {\n        return (z) = > {\n            return performOp(x,y,z)\n        }\n    }\n}</code></pre>\n\n\n\n<p>Каррирование создаёт вложенные функции в соответствии с числом аргументов в ней. Каждая функция тут получает свой аргумент. Если нет аргумента, то нет и каррирования.</p>\n\n\n\n<p id=\"90b9\">Каррирование работает для функций с числом аргументов больше двух — Wikipedia.</p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>Каррирование преобразует функцию в последовательность других функций, каждая из которых берёт по одному аргументу каррированной функции.</p></blockquote>\n\n\n\n<p>Могут быть случаи в которых карррование и частичное применение пересекаются. Предположим, что у нас есть такая функция:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>function div(x,y) {\n    return x/y;\n}</code></pre>\n\n\n\n<p>Если мы применим частичное применение, то получим вот что:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>function div(x) {\n    return (y) => {\n        return x/y;\n    }\n}</code></pre>\n\n\n\n<p>И каррирование даст нам такой же результат:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>function div(x) {\n    return (y) => {\n        return x/y;\n    }\n}</code></pre>\n\n\n\n<p id=\"044e\">Хоть эти два подхода и дают схожий результат, все же по сути они разные.</p>\n\n\n\n<p id=\"9765\">Как мы раньше говорили, каррирование и частичное применение схожи, но внутри у них всё по-другому. Общее у них то, что при работе они зависят от замыканий.</p>\n\n\n\n<h2 id=\"748a\">А каррирование действительно полезно?</h2>\n\n\n\n<p id=\"b6f0\">Естественно, этот подход очень удобен если вам надо:</p>\n\n\n\n<p id=\"4408\"><strong>Написать небольшие модули кода, которые можно переиспользовать и конфигурировать с легкостью, как и с npm:</strong></p>\n\n\n\n<p id=\"3300\">Для примера у вас есть магазин и вы хотите дать 10% скидку вашим любимым клиентам:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>function discount(price, discount) {\n    return price * discount\n}</code></pre>\n\n\n\n<p>Когда один из таких клиентов что-нибудь покупает на 500$, то вы её даёте ему:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>const price = discount(500,0.10); // $50 \n// $500  - $50 = $450</code></pre>\n\n\n\n<p>Тут вы понимаете, что этот процесс будет происходить ежедневно:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>const price = discount(1500,0.10); // $150\n// $1,500 - $150 = $1,350\nconst price = discount(2000,0.10); // $200\n// $2,000 - $200 = $1,800\nconst price = discount(50,0.10); // $5\n// $50 - $5 = $45\nconst price = discount(5000,0.10); // $500\n// $5,000 - $500 = $4,500\nconst price = discount(300,0.10); // $30\n// $300 - $30 = $270</code></pre>\n\n\n\n<p>Мы можем просто каррировать функцию скидки, чтобы нам не пришлось всегда добавлять&nbsp;<code>0.10</code>.</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>function discount(discount) {\n    return (price) => {\n        return price * discount;\n    }\n}\n\nconst tenPercentDiscount = discount(0.1);</code></pre>\n\n\n\n<p>Теперь нам нужна только цена для расчета стоимости со скидкой:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>tenPercentDiscount(500); // $50\n// $500 - $50 = $450</code></pre>\n\n\n\n<p id=\"461e\">И снова, так получается, что некоторые клиенты уж очень нам важны, важнее других. И мы хотим им дать скидку уже в 20%.</p>\n\n\n\n<p id=\"5c1f\">Тут мы будем использовать нашу каррированую функцию скидки:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>const twentyPercentDiscount = discount(0.2);</code></pre>\n\n\n\n<p id=\"449c\">Мы делаем новую функцию для наших очень важных клиентов, вызывая функцию каррирования со значением&nbsp;<code>0.2</code>, что есть 20%.</p>\n\n\n\n<p id=\"cd48\">Отдаваемая функция&nbsp;<code>twentyPercentDiscount</code>&nbsp;будет использоваться для расчета скидок у таких важных клиентов:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>twentyPercentDiscount(500); // 100\n// $500 - $100 = $400\ntwentyPercentDiscount(5000); // 1000\n// $5,000 - $1,000 = $4,000\ntwentyPercentDiscount(1000000); // 200000\n// $1,000,000 - $200,000 = $600,000</code></pre>\n\n\n\n<p id=\"93b4\"><strong>Ещё мы можем избегать частых вызовов функций с одним и тем же аргументом:</strong></p>\n\n\n\n<p id=\"d984\">Для примера, у нас есть функция для расчета объема цилиндрического объекта:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>function volume(l, w, h) {\n    return l * w * h;\n}</code></pre>\n\n\n\n<p>Так получается, что все они с высотой в 100m. Это приведет к вызову функции с повторяющимся аргументом&nbsp;<code>h = 100</code>.</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>volume(200,30,100) // 2003000l\nvolume(32,45,100); //144000l\nvolume(2322,232,100) // 53870400l</code></pre>\n\n\n\n<p>Чтобы решить эту проблему, мы каррируем функцию&nbsp;<code>volume</code>:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>function volume(h) {\n    return (w) => {\n        return (l) => {\n            return l * w * h\n        }\n    }\n}</code></pre>\n\n\n\n<p>Теперь мы можем сделать специальную функцию для цилиндров с конкретной высотой:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>const hCylinderHeight = volume(100);\nhCylinderHeight(200)(30); // 600,000l\nhCylinderHeight(2322)(232); // 53,870,400l</code></pre>\n\n\n\n<h2 id=\"1dec\">Основа для создания каррирования</h2>\n\n\n\n<p id=\"5a3f\">Давайте сделаем функцию, которая берёт любую функцию и отдаёт каррированную версию этой функции.</p>\n\n\n\n<p id=\"587e\">Для этого мы можем сделать так:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>function curry(fn, ...args) {\n    return (..._arg) => {\n        return fn(...args, ..._arg);\n    }\n}</code></pre>\n\n\n\n<p id=\"039b\">Что тут произошло? Наша функция каррирования принимает функцию (<code>fn</code>), которую мы хотим, собственно, каррировать и также неизвестное число параметров(<code>…args</code>). Rest оператор используется, чтобы собрать все параметры после&nbsp;<code>fn</code>&nbsp;в&nbsp;<code>…args</code>.</p>\n\n\n\n<p id=\"2c37\">Далее, мы отдаём функцию, которая также собирает все остаточные параметры как&nbsp;<code>…_args</code>. Эта функция вызывает изначальную функцию fn, передавая ей&nbsp;<code>…args</code>&nbsp;и&nbsp;<code>…_args</code>&nbsp;используя&nbsp;<a href=\"https://medium.com/@stasonmars/%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80-spread-%D0%B8-rest-%D0%BF%D0%B0%D1%80%D0%B0%D0%BC%D0%B5%D1%82%D1%80%D1%8B-%D0%B2-javascript-22eb33cb0825\">spread оператор</a>&nbsp;для параметров, далее значение отдаётся пользователю.</p>\n\n\n\n<p id=\"7880\">Теперь мы можем использовать нашу собственную функцию для каррирования нужных функций.</p>\n\n\n\n<p id=\"27e5\">Давайте применим эту функцию для создания более специфичной функции по расчёту объёма стометровых цилиндров:</p>\n\n\n\n<pre class=\"wp-block-code javascript\"><code>function volume(l,h,w) {\n    return l * h * w\n}\nconst hCy = curry(volume,100);\nhCy(200,900); // 18000000l\nhCy(70,60); // 420000l</code></pre>\n\n\n\n<h2 id=\"a1b9\">Заключение</h2>\n\n\n\n<p id=\"9f2e\">Замыкания делают каррирование возможным. Возможность сохранять состояние уже выполненных функций даёт нам возможность для создания фэктори-функций, которые могут давать точное значение аргументу.</p>\n\n\n\n<p id=\"71a2\">Каррирование очень коварное дело поначалу, учитывая замыкания и функциональное программирование. Но я убеждаю вас, что со временем и постоянной практикой, вы полностью его поймете и увидите всю его ценность.</p>\n\n\n\n<p id=\"358d\">Ссылки:</p>\n\n\n\n<p id=\"5be8\"><a href=\"https://ru.wikipedia.org/wiki/%D0%9A%D0%B0%D1%80%D1%80%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5\">Каррирование</a></p>\n\n\n\n<p id=\"6183\"><a href=\"https://ru.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5\">Частичное применение</a></p>\n","type":"js","date":"2021-02-01T16:48:24.000Z","acf":{"seo_desc":"В этой статье вы простым языком поймете работу с каррированием в JavaScript и увидите рабочие примеры его применения.","keywords":"каррирование в javascript, карринг в javascript, каррирование js","pub_date":"2020-03-06","tags":"JavaScript, Функции, Каррирование"},"title":"Понимаем каррирование в JavaScript","id":"6a1ff13a-ed43-5409-ac7c-2badd1566a47","excerpt":"<p>В этой статье вы простым языком поймете работу с каррированием в JavaScript и увидите рабочие примеры его применения.</p>\n","featured_media":{"source_url":"https://stasonmars.ru/wp/wp-content/uploads/2021/02/curryingjskfds.jpg"},"interesting":[{"title":"Погружаемся в работу с children на React","slug":"pogruzhaemsya-v-raboty-s-children-na-react","type":"js"},{"title":"Понимаем каррирование в JavaScript","slug":"ponimaem-carrirovanie-v-javascript","type":"js"},{"title":"useEffect(fn, []) это не новый componentDidMount()","slug":"useeffect-eto-ne-novyi-componentdidmount","type":"js"}]}},"staticQueryHashes":["3576131997","63159454"]}