Концепции функционального программирования с практическими примерами
Что такое функциональное программирование?
Функциональное программирование - это стиль кодирования, основанный на использовании функций в ваших программах. Это подход к разработке программного обеспечения, основанный на оценке функций. Он разбивает программу на маленькие и проверяемые части. Вы можете комбинировать базовые функции разными способами для создания все более и более сложных программ.
Функциональное программирование следует нескольким основным принципам. Один из этих принципов заключается в том, что функции не зависят от состояния программы или глобальных переменных. Они зависят от переданных в них аргументов. Другой принцип функционального программирования заключается в том, что функции имеют минимальные побочные эффекты в программе. В дополнение к этому они пытаются ограничить любые изменения состояния программы и избежать изменений глобальных объектов, содержащих данные.
В этой статье мы рассмотрим некоторые полезные концепции функционального программирования на JavaScript. Давайте приступим к делу.
1. Чистые функции
Чистая функция - это функция, которая для ввода возвращает тот же вывод, не изменяя ничего за пределами своей области видимости. Взгляните на примеры ниже:
Первая версия:
let age = 19 function getMyAge() { console.log(`I'm ${age} years old.`) } getMyAge(age) //Returns:
I'm 19 years old.age = 20 getMyAge(age) //Returns:
I'm 20 years old.
Вторая версия:
function getMyAge(age) { return `I'm ${age} years old.` } getMyAge(19) //Returns:
I'm 19 years old.getMyAge(20) //Returns:
I'm 20 years old.
В первой версии функция ищет переменную вне вашей области видимости, каким-то образом изменяя мир. В этом случае идеальный результат возвращает только значение, и если мы вызываем функцию с тем же аргументом (даже если аргумент отсутствует), мы получаем другое значение. В чистой функции этого не происходит, потому что это зависит только от ее входных данных и аргументов.
2. Побочные эффекты
Побочный эффект - это любое взаимодействие с нашим внешним миром, которое происходит во время вычислений, а не с использованием чистых функций. Наш код может быть более предсказуемым, потому что результаты зависят только от их входных данных. Если мы знаем, как выглядит наша функция и какие входные данные она получает, мы можем предсказать результат. Взгляните на пример ниже:
var double = function(value){ return value * 2; } var initialValue = 30; double(initialValue); // 60 initialValue; // Still 30.
3. Изменчивость
Мутация связана с изменчивостью вещей. В функциональном программировании изменчивость не приветствуется. Когда у нас есть неизменяемые данные, их состояние не может измениться после того, как вы их создали. Если вам нужно что-то изменить, вам придется создать новое значение.
Изменяемый пример:
function changeFirstElem(array) {
array[0] = 'Lose yourself to dance'
}
const daftPunkPopSongs = ['Instant Crush', 'Get Lucky', 'One More Time'];
changeFirstElem(daftPunkPopSongs);
console.log(daftPunkPopSongs); //
["Lose yourself to dance", "Get Lucky", "One More Time"].
Неизменяемый пример:
function changeFirstElem(array) { const modifiedArray = ['Lose yourself to dance', ...array]; return modifiedArray; } const daftPunkPopSongs = ['Instant Crush', 'Get Lucky', 'One More Time']; const modifiedArray = changeFirstElem(daftPunkPopSongs);
Console.log(daftPunkPopSongs); // Returns: ['Instant Crush', 'Get Lucky', 'One More Time'].
Это круто. Во втором примере мы сделали вещи безопаснее, в нашем коде сложнее находить ошибки. Если результат неверен, мы уверены, что проблема в нашей функции, а не в случайных взаимодействиях. Это упростит отладку нашего кода.
4. Функции высшего порядка.
Любая функция, которая принимает другую функцию в качестве аргумента, называется функцией высшего порядка. JavaScript предоставляет несколько полезных функций высшего порядка для удобного управления данными.
Вот некоторые из важных функций, которые вам следует знать:
Метод map, который помогает передать функцию для преобразования каждого элемента в массиве.
const numbers = [1, 2, 3];
const doubles = numbers.map(num => num * 2) //[2, 4, 6]
фильтр получает набор данных, и вы можете передать условную функцию, которая возвращает подмножество коллекции.
const numbers = [1, 2, 3];
const isGreaterThanOne = numbers.filter(num => num > 1) //[2, 3]
Метод reduce, который принимает функцию с двумя аргументами (аккумулятор и элемент). Мы также можем вернуть общее количество всех элементов массива, используя метод reduce, как мы это делали в примере ниже.
const numbers = [1, 2, 3];
const mySum = numbers.reduce((accumulator, num) => accumulator + num) // returns: 6.
5. Каррирование и частичное применение
Каррирование функции означает преобразование ее из функции, имеющей несколько аргументов, в несколько функций с одним единственным аргументом. Взгляните на пример ниже:
//Un-curried function
function unCurried(x, y) {
return x + y;
}
//Curried function
function curried(x) {
return function(y) {
return x + y;
}
}
//Alternative using ES6
const curried = x => y => x + y
curried(1)(2) // Returns 3
Каррирование полезно в вашей программе, если вы не можете передать все аргументы функции одновременно.
Теперь давайте посмотрим на Частичное приложение, которое можно описать как применение нескольких аргументов к функции за раз и возвращение другой функции, которая применяется к большему количеству аргументов. Вот пример:
//Impartial function
function impartial(x, y, z) {
return x + y + z;
}
var partialFn = impartial.bind(this, 1, 2);
partialFn(10); // Returns 13
Заключение
Функциональное программирование - хорошая привычка. Это упрощает управление вашим кодом и избавляет вас от скрытых ошибок. Это мощный подход при работе с JavaScript или другими языками программирования.
Спасибо, что прочитали эту статью, надеюсь, вы нашли ее полезной. Если да, то получите больше похожего контента, подписавшись на наш канал на YouTube в Decoded!