Funktionale Programmierung in JavaScript: Fortgeschrittene Techniken

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einführung in die funktionale Programmierung auf fortgeschrittenem Niveau

\n\n

Funktionale Programmierung (FP) ist ein Paradigma, das Berechnungen als Ausführung mathematischer Funktionen betrachtet und die Veränderung von Zuständen und veränderlichen Daten vermeidet. In JavaScript, insbesondere in der Node.js-Umgebung, wird FP aufgrund seiner Vorhersagbarkeit, Testbarkeit und Parallelität immer beliebter.

\n\n

Wenn Sie bereits die Grundlagen der FP beherrschen (reine Funktionen, Funktionen höherer Ordnung, map, filter, reduce), ist es an der Zeit, zur nächsten Stufe überzugehen. In diesem Artikel behandeln wir fortgeschrittene Konzepte: Currying, Komposition, Monaden und die Arbeit mit unveränderlichen Daten.

\n\n

1. Currying und partielle Anwendung

\n\n

Was ist Currying?

\n

Currying ist der Prozess der Umwandlung einer Funktion, die mehrere Argumente akzeptiert, in eine Folge von Funktionen, von denen jede ein Argument akzeptiert. Dies ermöglicht die Erstellung spezialisierter Funktionen auf der Grundlage allgemeiner Funktionen.

\n\n
// Normale Funktion\nconst add = (a, b, c) => a + b + c;\nconsole.log(add(1, 2, 3)); // 6\n\n// Curry-Version\nconst curriedAdd = a => b => c => a + b + c;\nconsole.log(curriedAdd(1)(2)(3)); // 6\n\n// Universelle Curry-Funktion\nconst curry = (fn) => {\n  const arity = fn.length;\n  const resolver = (...args) => {\n    if (args.length < arity) {\n      return (...nextArgs) => resolver(...args, ...nextArgs);\n    }\n    return fn(...args);\n  };\n  return resolver;\n};\n\nconst multiply = (a, b, c) => a * b * c;\nconst curriedMultiply = curry(multiply);\nconsole.log(curriedMultiply(2)(3)(4)); // 24\nconsole.log(curriedMultiply(2, 3)(4)); // 24
\n\n

Partielle Anwendung

\n

Partielle Anwendung ist das Fixieren eines Teils der Argumente einer Funktion, wodurch eine neue Funktion mit weniger Argumenten entsteht. Im Gegensatz zum Currying erfordert die partielle Anwendung keine strenge Reihenfolge der Aufrufe.

\n\n
const partial = (fn, ...presetArgs) => (...laterArgs) => fn(...presetArgs, ...laterArgs);\n\nconst greet = (greeting, name) => `${greeting}, ${name}!`;\nconst sayHello = partial(greet, 'Hello');\nconst sayHi = partial(greet, 'Hi');\n\nconsole.log(sayHello('Alice')); // Hello, Alice!\nconsole.log(sayHi('Bob'));     // Hi, Bob!
\n\n

2. Funktionskomposition

\n\n

Fortgeschrittene Komposition

\n

Komposition ist der Prozess der Kombination mehrerer Funktionen zur Erstellung einer neuen Funktion. In der fortgeschrittenen FP verwenden wir die Komposition von rechts nach links (compose) und von links nach rechts (pipe).

\n\n
// Einfache Komposition (von rechts nach links)\nconst compose = (...fns) => (value) => fns.reduceRight((acc, fn) => fn(acc), value);\n\n// Komposition von links nach rechts (pipe)\nconst pipe = (...fns) => (value) => fns.reduce((acc, fn) => fn(acc), value);\n\n// Beispiel: Zeichenkettenverarbeitung\nconst trim = (str) => str.trim();\nconst toLowerCase = (str) => str.toLowerCase();\nconst capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);\nconst removeSpaces = (str) => str.replace(/\\s+/g, '-');\n\nconst slugify = compose(capitalize, toLowerCase, trim, removeSpaces);\n// Äquivalent: removeSpaces(trim(toLowerCase(capitalize("  Hello World  "))))\n\nconsole.log(slugify('  Hello World  ')); // Hello-world
\n\n

Transducer

\n

Transducer sind eine Komposition von Transformationsfunktionen, die mit beliebigen iterierbaren Datenstrukturen arbeiten. Sie ermöglichen die Kombination mehrerer Operationen (z. B. map und filter) in einem einzigen Durchlauf.

\n\n
const transducer = (mapper, predicate) => (reducer) => (acc, value) => {\n  const mapped = mapper(value);\n  return predicate(mapped) ? reducer(acc, mapped) : acc;\n};\n\nconst double = (x) => x * 2;\nconst isEven = (x) => x % 2 === 0;\n\nconst processNumbers = transducer(double, isEven);\nconst sumReduc                

Blogs

Buchempfehlungen