Фронтенд и пять подонков для изучения JavaScript — каррирование функций

JavaScript
Фронтенд и пять подонков для изучения JavaScript — каррирование функций

Прежде чем читать этот блог, вам нужно хорошо понимать замыкания в JavaScript, вы можете прочитать то, что я писал ранее«Front-end сразится с пятью подонками, чтобы выучить JavaScript — закрытие»

Я думаю, что каждый читает этот блог с пониманием замыканий.

В последнее время меня ничего не интересует, я не хочу ничего делать, я не хочу ничему учиться, и я не хочу играть в игры. . . Привет. . Но я недавно смотрел отечественный мультипликационный фильм "Дьявольское дитя Нежи", чувствую, что уровень отечественной мультипликации действительно становится все выше и выше, это очень хорошо, это стоит посмотреть

Что такое каррирование функций

каррирование функций(Функция карри), функция сделала вкус карри? ? На самом деле, я впервые услышал это слово, я чувствовал себя хорошо на высоких ах, транслитерации, глубоких, и поэтому я смотрю книги («Расширенное программирование на JavaScript»), а также некоторые из их предшественников, позже написал блог и обнаружил, что функция карриИспользуйте замыкание для возврата функции

Каррированные функции могут задерживать получение параметров.Например,мне нужно получить два параметра для функции.При ее выполнении я должен получить два параметра.Иначе я не могу ее выполнить.Разве не легко вызвать проблемы. Однако каррированная функция может сначала получить функцию, а потом получить функцию, это слишком грубо, так что давайте рассмотрим простой пример (и самый распространенный пример во всей сети)⬇️

Это нормальная функция

// 正常我们声明函数的时候是这样的
function 求两数之和(第一个数, 第二个数) {
  return 第一个数 + 第二个数
}
const 和 = 求两数之和(1, 2);
console.log(`两数之和为 ${和}`); // 3

Так как же выглядит функция, которую мы пишем в соответствии с каррированием?

// 理解柯里化的思想
function 求两数之和(第一个数) {
  return function (第二个数) {
    return 第一个数 + 第二个数
  }
}
// 第一种方法
const 和 = 求两数之和(1)(2);
console.log(`第一种方法的两个数之和为 ${和}`);
// 第二种方法
const 已接收第一个数的求和函数 = 求两数之和(1);
const 两个数都已接收的和 = 已接收第一个数的求和函数(2);
console.log(`第二种方法的两个数之和为 ${两个数都已接收的和}`);

Из приведенного выше сравнения функций мы можем обнаружить, что каррированная функция может сначала получить функцию, а затем, когда нам нужно передать второй параметр, мы передаем его и выполняем окончательный результат.

Таким образом, мы можем динамически генерировать функции с одним и тем же первым параметром и другим вторым параметром или с тем же вторым параметром и другим первым параметром.

функция, которая выполняет функцию

Метод приведен в известном «Продвинутом программировании на JavaScript». Этот метод позволяет нам преобразовать функцию, не поддерживающую каррирование, в функцию, поддерживающую идеи каррирования.

function 把函数柯里化(需要柯里化的函数) {
  const 调用柯里化时除了函数以外的参数 = Array.prototype.slice.call(arguments, 1);
  return function () {
    const 后接受的参数 = [...arguments];
    const 最终的参数 = [...调用柯里化时除了函数以外的参数, ...后接受的参数];
    return 需要柯里化的函数.apply(null, 最终的参数);
  }
}

function 求两数之和(第一个数, 第二个数) {
  return 第一个数 + 第二个数
}

const 柯里化的求两数之和 = 把函数柯里化(求两数之和, 1);

console.log(
  `被柯里化后的函数求的两数之和为 ${
    柯里化的求两数之和(2)
  }`
); // 被柯里化后的函数求的两数之和为 3

Мы обнаружили, что можем написать функцию в одиночку, а затем преобразовать обычную функцию в функцию, поддерживающую каррирование, но этот метод, предоставляемый продвинутым программированием, может обеспечить только два вызова, что это значит? Давайте посмотримlodashсерединаcurryкак реализован метод

const _ = require('lodash');

function 求三个数之和(第一个数, 第二个数, 第三个数) {
  return 第一个数 + 第二个数 + 第三个数
}

const 柯里化后的求三个数之和 = _.curry(求三个数之和);

console.log(柯里化后的求三个数之和(1)(2)(3)); // 6
console.log(柯里化后的求三个数之和(1)(2, 3)); // 6
console.log(柯里化后的求三个数之和(1, 2, 3)); // 6

Теперь мы видим,lodashВ процессе преобразования каррирования мы можем вызывать каррированную функцию произвольно, независимо от того, как передаются параметры, лишь бы проходов было три, сколько бы раз они ни были.

Давайте сами создадим каррированную функцию

Каковы наши потребности?

feature

  1. нужно преобразовать обычные функции в функции карри
  2. Пока параметры не достигают количества преобразованных функций, возвращаем функцию и сохраняем переданные параметры
  3. Когда количество поддерживаемых параметров не достигает количества преобразуемых функций, бесконечные вызовы

Тогда давайте посмотрим на функции, которые нам нужно конвертировать ⬇️

const 封神榜 = (名字, 宝物, 出生地) => console.log(`我是${出生地}的${名字},我有${宝物}`);

封神榜('哪吒', '乾坤圈', '陈塘关'); // 我是陈塘关的哪吒,我有乾坤圈

Посмотрите, как выглядит результат нашей обычной конвертации ⬇️

const 封神榜 = 名字 => 宝物 => 出生地 => console.log(`我是${出生地}的${名字},我有${宝物}`);

封神榜('哪吒')('乾坤圈')('陈塘关');

Для обычных функций трансформации мы не очень вольны в передаче параметров.Приходится одевать их три раза,и передавать по одной.Тогда будет офигенно⬇️

const 封神榜 = (名字, 宝物, 出生地) => console.log(`我是${出生地}的${名字},我有${宝物}`);

const 柯里化 = (需要柯里化的函数, ...参数) => 需要柯里化的函数.length <= 参数.length
  ? 需要柯里化的函数(...参数)
  : (...更多参数) => 柯里化(需要柯里化的函数, ...参数, ...更多参数);

const 柯里化后的封神榜 = 柯里化(封神榜);

柯里化后的封神榜('哪吒', '乾坤圈', '陈塘关'); // 我是陈塘关的哪吒,我有乾坤圈
柯里化后的封神榜('孙悟空')('金箍鲁棒')('花果山'); // 我是花果山的孙悟空,我有金箍鲁棒
柯里化后的封神榜('雷震子', '黄金棍')('终南山玉柱洞'); // 我是终南山玉柱洞的雷震子,我有黄金棍
柯里化后的封神榜()()()()()()()()('姜子牙', '打神鞭', '昆仑山'); // 我是昆仑山的姜子牙,我有打神鞭

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

Конечно, если есть каррирование, будет и антикаррирование, но я не думаю, что это необходимо.Поскольку я уже каррировал, то каррированная функция, конечно, поддерживает метод передачи параметров некаррирующих функций, но я интересно. Друзья, вы все еще можете понять

Суммировать

На самом деле, мы, возможно, раньше не слышали о концепции каррирования функций, но мы могли более или менее сталкиваться с этим методом в нашей работе или исследовании, но мы просто не знаем, что написание this является каррированием, а эта функция является каррирующей функцией.

Метод каррированных функций по-прежнему очень практичен, и все еще есть места, где это требование необходимо в ежедневном процессе разработки.


Я первопроходец войны пятерки, ученик начальной школы в мире фронтенда.