7 техник функционального программирования для разработчиков JavaScript

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

В этой статье я расскажу о семи приемах функционального программирования, которые вы можете использовать в JavaScript, чтобы вы лучше понимали, как применять функциональное программирование в своих проектах веб-разработки.

1. Чистые функции

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

const helloWorld = (name) => `Hi ${name}`;
helloWorld(‘Piumi’);
Вход в полноэкранный режим Выход из полноэкранного режима

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

Мы всегда должны стремиться к тому, чтобы область видимости каждой переменной была как можно меньше, локализуя переменные как можно больше при их создании. Чистые функции не зависят ни от чего, кроме своих параметров, и поэтому их поведение предсказуемо. Если параметры одинаковы, то и результат будет одинаковым. Это значительно улучшает тестируемость вашего кода.

2. Избегайте процедурных циклов

Отличительной особенностью чистого функционального программирования является неизменяемость. Вам придется отказаться от стандартных методов циклов, таких как for, while и do-while, чтобы избежать изменения переменных после их инициализации (например, счетчиков цикла). Вместо этого JavaScript предлагает функции более высокого порядка, такие как map, filter, reduce и foreach, чтобы абстрагировать итерационные процессы.

Рассмотрим несколько примеров с использованием функций foreach, map, filter и reduce.

foreach(): Функция вызывается для каждого элемента массива.

let sum = 0;
const numbers = [10, 25, 73, 84];
numbers.forEach(addNumbers);

function addNumbers(number) {
  sum += number;
}
Вход в полноэкранный режим Выход из полноэкранного режима

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

array.map(mapper)
Вход в полноэкранный режим Выход из полноэкранного режима

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

array.filter(condition);
Вход в полноэкранный режим Выход из полноэкранного режима

reduce(): Функция, которая уменьшает массив до одного значения. В следующем фрагменте кода параметр reducer — это функция, которая возвращает новое значение из накопленного значения и следующего элемента массива. Она вызывается таким образом для каждого значения в массиве по очереди.

array.reduce(reducer);
Вход в полноэкранный режим Выход из полноэкранного режима

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

const computers= [  
 { make: 'ASUS', model: 'CT-0019', type: 'PC', price: 25000}, 
 { make: 'DELL', model: 'DX-001', type: 'PC', price: 16800},  
 { make: 'ASUS', model: 'CT-0011', type: 'LAPTOP', price: 79800},  
 { make: 'ASUS', model: 'CT-0209', type: 'LAPTOP', price: 65400},  
 { make: 'DELL', model: 'DX-005', type: 'PC', price: 34500},  
 { make: 'DELL', model: 'DX-001', type: 'LAPTOP', price: 35000},  
 { make: 'HP', model: 'HP-003', type: 'PC', price: 36500},  
 { make: 'HP', model: 'HP-025', type: 'PC', price: 50000},  
 { make: 'DELL', model: 'DX-004', type: 'LAPTOP', price: 87000},  
 { make: 'HP', model: 'HP-324', type: 'PC', price: 46000}
];

const averageComputerPrice = computers
  .filter(c => c.type === 'LAPTOP')  
  .map(c => c.price)  
  .reduce((sum, price, i, array) => sum + price / array.length, 0); 
console.log(averageComputerPrice);
Войти в полноэкранный режим Выйти из полноэкранного режима

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

3. Цепочка функций

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

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

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

var obj = {
 output: 0,
 addNumber: function(p, q) {
   this.output= p + q; 
   return this;
 },
multiplyNumber: function(p) {
   this.output= this.output * p;
   return this;
 } 
};

obj.addNumber(10, 20).multiplyNumber(10)
console.log(obj.output)
Вход в полноэкранный режим Выход из полноэкранного режима

В приведенном выше примере кода, поскольку функция addNumber отражает текущий объект obj, возвращаемое значение содержит дополнительные функции. Мы запускаем вторую функцию, multiplyNumber, на том же объекте, чтобы связать их вместе.

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

4. Керринг

Керринг — это процесс разбиения многоаргументной функции на последовательность унарных (с одним аргументом) функций высшего порядка. Другими словами, функция с тремя параметрами, f(p,q,r), структурно расширяется до трех функций, работающих с одним аргументом за раз, f(p) -> f(q) -> f(r).

Рассмотрим следующий пример.

function fsum (a,b) {
  return a+ b
}
//Currying
function fsum_curry (a) {
  return function(b) {
    return a + b
  }
}
fsum(10, 2) // 12
fsum_curry(10)(2) // 12
Вход в полноэкранный режим Выход из полноэкранного режима

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

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

Мы часто путаем частичное применение и каррирование, хотя это две разные концепции. Например, функция curried всегда остается функцией curried, даже если мы не передаем ей никаких аргументов. Частичное применение происходит, когда мы передаем функции некоторые аргументы, но не все. Currying — популярный метод для выполнения частичного применения, но это не единственный вариант.

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

function havingMeal(verb) {
  // Outer function
  return function(input) {
    // Inner function
    return "I'm " + verb + " " + input + " ."
  }
}
// Partially apply 'havingMeal'
var haveLunch = havingMeal('eating')
var haveTea = havingMeal('drinking')
haveLunch('lunch')
//"I'm eating lunch."
haveTea('coffee')
//"I'm drinking coffee."
Вход в полноэкранный режим Выход из полноэкранного режима

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

haveLunch(‘lunch’) === prepareLunch(‘eating’)(‘lunch’)
Вход в полноэкранный режим Выйти из полноэкранного режима

6. Композиция

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

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

const split = (string) => string.split('_').join(' ');

const lowerCase = (string) => string.toLowerCase();

console.log(lowerCase(split('APPLE_TREE'))); //apple tree
Вход в полноэкранный режим Выход из полноэкранного режима

7. Рекурсия

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

function factorial(n, product = 1) {  
  if (n === 0) {    
    return product;  
 }  
    return factorial(n - 1, product * n)
}
Вход в полноэкранный режим Выход из полноэкранного режима

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

Заключение

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

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

Спасибо за чтение!

Syncfusion Essential JS 2 — это единственный набор, который вам когда-либо понадобится для создания приложений. Он содержит более 65 высокопроизводительных, легких, модульных и отзывчивых компонентов пользовательского интерфейса в одном пакете. Загрузите бесплатную пробную версию, чтобы оценить элементы управления уже сегодня.

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

Похожие блоги

  • 11 консольных методов в JavaScript для эффективной отладки
  • Обработка одновременных запросов с помощью обратных вызовов JavaScript
  • Простое создание заполняемой формы с помощью текстового процессора JavaScript
  • 7 лучших техник деструктуризации объектов JavaScript

Оцените статью
devanswers.ru
Добавить комментарий