Сделайте код более легким для чтения с помощью функционального программирования

sdelajte kod bolee legkim dlya chteniya s pomoshhyu funkczionalnogo programmirovaniya

Откройте для себя функциональный JavaScript был назван одним из лучшие новые книги по функциональному программированию от BookAuthority!

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

Связывание

Связывание это техника, которая используется для упрощения кода, когда несколько методов применяются к объекту один за другим.

Давайте рассмотрим и сравним два стиля: императивный и функциональный. В функциональном стиле я использую базовый инструментарий для операций со списком filter() и map() . Затем я объединяю их цепью.

Я взял за дело сборник задач. Задание имеет idописание (desc) логическое значение completedа type и назначен user объект. Пользовательский объект a name собственность.

//Imperative style
let filteredTasks = [];
for(let i=0; i<tasks.length; i++){
    let task = tasks[i];
    if (task.type === "RE" && !task.completed) {
        filteredTasks.push({ ...task, userName: task.user.name });
    }
}

//Functional style
function isPriorityTask(task){
   return task.type === "RE" && !task.completed;
}

function toTaskView(task) {
   return { ...task, userName: task.user.name };
}

let filteredTasks = tasks.filter(isPriorityTask).map(toTaskView);

Обратите внимание на обратные вызовы для filter() и map() как чистые функции с намерением раскрывать имена.

map() преобразует список значений в другой список значений с помощью функции отображения.

Вот тест производительности, измеряющий разницу между двумя стилями. Кажется, что функциональный подход на 60% медленнее. Когда императивный процесс завершится через 10 миллисекунд, функциональный подход завершится через 16 миллисекунд. В этом случае использование императивного цикла будет преждевременной оптимизацией.

Стиль без точек

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

tasks.filter(task => isPriorityTask(task)).map(task => toTaskView(task));

В безпунктовом стиле пишется без аргументов:

tasks.filter(isPriorityTask).map(toTaskView);

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

Частичное применение

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

Частичное применение относится к процессу фиксации ряда аргументов функции.

Это способ перехода от обобщения к специализации.

Для частичного применения мы можем использовать partial() из популярной библиотеки, например, underscore.js или lodash.js. The bind() метод также может выполнять частичное применение.

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

let filteredTasks = [];
for(let i=0; i<tasks.length; i++){
    let task = tasks[i];
    if (task.type === "NC") {
        filteredTasks.push(task);
    }
}

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

Функция предиката это функция, принимающая одно значение как входные данные и возвращающая истину/ложность в зависимости от того, соответствует ли значение условию.

function isTaskOfType(type, task){
  return task.type === type;
}

let isCreateNewContent = partial(isTaskOfType, "NC");
let filteredTasks = tasks.filter(isCreateNewContent);

Обратите внимание на функцию предиката. Он носит название, которое выражает его намерение. Когда я читаю tasks.filter(isCreateNewContent) Я четко понимаю, что за tasks Я отнимаю.

filter() выбирает значения из списка на основе функции предиката, определяющей, какие значения следует сохранить.

Уменьшить

Я начну новый пример из списка покупок. Вот как может выглядеть список:

let shoppingList = [
   { name : "orange", units : 2, price : 10, type : "FRT"},
   { name : "lemon", units : 1, price : 15, type : "FRT"},
   { name : "fish", units : 0.5, price : 30, type : "MET"}
];

Я рассчитаю общую стоимость и цену только на фрукты. Ниже приведен императивный стиль:

let totalPrice = 0, fruitsPrice = 0;
for(let i=0; i<shoppingList.length; i++){
   let line = shoppingList[i];
   totalPrice += line.units * line.price;
   if (line.type === "FRT") {
       fruitsPrice += line.units * line.price;
   }
}

Функциональный подход в этом случае потребует использования reduce() чтобы вычислить общую цену.

reduce() сокращает список значений до одного значения.

Как мы делали ранее, мы создаем новые функции для необходимых обратных вызовов и предоставляем им раскрывающие намерения имена: addPrice() и areFruits().

function addPrice(totalPrice, line){
   return totalPrice + (line.units * line.price);
}

function areFruits(line){
   return line.type === "FRT";
}

let totalPrice = shoppingList.reduce(addPrice,0);
let fruitsPrice = shoppingList.filter(areFruits).reduce(addPrice,0);

Вывод

Чистые функции легче читать и размышлять.

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

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

Откройте для себя функциональный JavaScript был назван одним из лучшие новые книги по функциональному программированию от BookAuthority!

Чтобы узнать больше о методах функционального программирования в React, просмотрите Функциональный React.

учиться функциональный Reactпроектно, с Функциональная архитектура с React и Redux.

Подпишитесь на Twitter

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *