🔍

Композиция функций в JavaScript

🗓️ 3 мая 2020 г. 2 мин. чтения

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

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

compose = (fn1, fn2) => (value) => fn2(fn1(value))

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

add2AndSquare = (n) => square(add2(n))

Мы можем использовать функцию высшего порядка (higher order function), чтобы упорядочить их.

add2AndSquare = compose(add2, square)

Простая реализация compose будет выглядеть так:

compose = (f1, f2) => (value) => f2(f1(value))

Чтобы получить большую гибкость, мы можем использовать функцию reduceRight:

compose = (...fns) => (initialVal) =>
  fns.reduceRight((val, fn) => fn(val), initialVal)

Примеры из разработки - добавления аутентификации, логирования или свойств контекста.

Вот несколько примеров, как можно использовать:

// example
const add2 = (n) => n + 2
const times2 = (n) => n * 2

const times2add2 = compose(add2, times2)
const add6 = compose(add2, add2, add2)

times2add2(2) // 6
add2tiems2(2) // 8
add6(2) // 8

Вы можете подумать, что это не относится к фронтенду, но это также полезно в SPA (single page application). Например, вы можете добавить поведение к компоненту React, используя функции высшего порядка:

function logProps(InputComponent) {
  InputComponent.prototype.componentWillReceiveProps = function (nextProps) {
    console.log('Current props: ', this.props)
    console.log('Next props: ', nextProps)
  }
  return InputComponent
}

// EnhancedComponent will log whenever props are received
const EnhancedComponent = logProps(InputComponent)

Заключение

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

Реализация compose присутствует во многих служебных библиотеках JavaScript (lodash, rambda и т. Д.).

Copyright © 2020