Suche…
Bemerkungen
Was ist funktionale Programmierung?
Functional Programming oder FP ist ein Programmierparadigma, das auf zwei Hauptkonzepten der Unveränderlichkeit und Zustandslosigkeit aufbaut. Das Ziel von FP besteht darin, Ihren Code lesbarer, wiederverwendbarer und tragbarer zu machen.
Was ist funktionales JavaScript?
Es gab eine Debatte , um JavaScript als funktionale Sprache zu bezeichnen oder nicht. Wie auch immer, wir können JavaScript aufgrund seiner Beschaffenheit unbedingt als funktional verwenden:
- Hat reine Funktionen
- Hat erstklassige Funktionen
- Hat eine Funktion höherer Ordnung
- Es unterstützt Unveränderlichkeit
- Hat Verschlüsse
- Rekursions- und Listentransforationsmethoden (Arrays) wie z. B. map, verkleinern, filtern usw.
Die Beispiele sollten jedes Konzept ausführlich behandeln und die hier bereitgestellten Links dienen nur als Referenz und sollten entfernt werden, sobald das Konzept dargestellt ist.
Funktionen als Argumente akzeptieren
function transform(fn, arr) {
let result = [];
for (let el of arr) {
result.push(fn(el)); // We push the result of the transformed item to result
}
return result;
}
console.log(transform(x => x * 2, [1,2,3,4])); // [2, 4, 6, 8]
Wie Sie sehen, akzeptiert unsere transform
zwei Parameter, eine Funktion und eine Collection. Es wird dann die Sammlung durchlaufen und Werte in das Ergebnis verschieben, wobei für jeden von ihnen fn
.
Kommt mir bekannt vor? Dies ist der Funktionsweise von Array.prototype.map()
sehr ähnlich!
console.log([1, 2, 3, 4].map(x => x * 2)); // [2, 4, 6, 8]
Funktionen höherer Ordnung
Im Allgemeinen werden Funktionen, die mit anderen Funktionen arbeiten, entweder als Argumente oder durch Rückgabe (oder beides), Funktionen höherer Ordnung genannt.
Eine Funktion höherer Ordnung ist eine Funktion, die eine andere Funktion als Argument annehmen kann. Beim Übergeben von Rückrufen verwenden Sie Funktionen höherer Ordnung.
function iAmCallbackFunction() {
console.log("callback has been invoked");
}
function iAmJustFunction(callbackFn) {
// do some stuff ...
// invoke the callback function.
callbackFn();
}
// invoke your higher-order function with a callback function.
iAmJustFunction(iAmCallbackFunction);
Eine Funktion höherer Ordnung ist auch eine Funktion, die eine andere Funktion als Ergebnis zurückgibt.
function iAmJustFunction() {
// do some stuff ...
// return a function.
return function iAmReturnedFunction() {
console.log("returned function has been invoked");
}
}
// invoke your higher-order function and its returned function.
iAmJustFunction()();
Identität Monade
Dies ist ein Beispiel für eine Implementierung der Identitätsmonade in JavaScript. Sie könnte als Ausgangspunkt für die Erstellung anderer Monaden dienen.
Basierend auf der Konferenz von Douglas Crockford über Monaden und Gonaden
Die Wiederverwendung Ihrer Funktionen wird durch die Flexibilität, die diese Monade bietet, und Kompositions-Albträume einfacher.
f(g(h(i(j(k(value), j1), i2), h1, h2), g1, g2), f1, f2)
lesbar, schön und sauber:
identityMonad(value)
.bind(k)
.bind(j, j1, j2)
.bind(i, i2)
.bind(h, h1, h2)
.bind(g, g1, g2)
.bind(f, f1, f2);
function identityMonad(value) {
var monad = Object.create(null);
// func should return a monad
monad.bind = function (func, ...args) {
return func(value, ...args);
};
// whatever func does, we get our monad back
monad.call = function (func, ...args) {
func(value, ...args);
return identityMonad(value);
};
// func doesn't have to know anything about monads
monad.apply = function (func, ...args) {
return identityMonad(func(value, ...args));
};
// Get the value wrapped in this monad
monad.value = function () {
return value;
};
return monad;
};
Es funktioniert mit primitiven Werten
var value = 'foo',
f = x => x + ' changed',
g = x => x + ' again';
identityMonad(value)
.apply(f)
.apply(g)
.bind(alert); // Alerts 'foo changed again'
Und auch mit Objekten
var value = { foo: 'foo' },
f = x => identityMonad(Object.assign(x, { foo: 'bar' })),
g = x => Object.assign(x, { bar: 'foo' }),
h = x => console.log('foo: ' + x.foo + ', bar: ' + x.bar);
identityMonad(value)
.bind(f)
.apply(g)
.bind(h); // Logs 'foo: bar, bar: foo'
Lass uns alles versuchen:
var add = (x, ...args) => x + args.reduce((r, n) => r + n, 0),
multiply = (x, ...args) => x * args.reduce((r, n) => r * n, 1),
divideMonad = (x, ...args) => identityMonad(x / multiply(...args)),
log = x => console.log(x),
substract = (x, ...args) => x - add(...args);
identityMonad(100)
.apply(add, 10, 29, 13)
.apply(multiply, 2)
.bind(divideMonad, 2)
.apply(substract, 67, 34)
.apply(multiply, 1239)
.bind(divideMonad, 20, 54, 2)
.apply(Math.round)
.call(log); // Logs 29
Reine Funktionen
Ein Grundprinzip der funktionalen Programmierung ist , dass es vermeidet den Anwendungszustand (Staatenlosigkeit) und Variablen außerhalb des Geltungsbereichs (Unveränderlichkeit) zu verändern.
Reine Funktionen sind Funktionen, die:
- Bei einer gegebenen Eingabe immer dieselbe Ausgabe zurückgeben
- Sie sind nicht auf Variablen außerhalb ihres Gültigkeitsbereichs angewiesen
- Sie ändern den Status der Anwendung nicht ( keine Nebenwirkungen ).
Schauen wir uns einige Beispiele an:
Reine Funktionen dürfen keine Variablen außerhalb ihres Gültigkeitsbereichs ändern
Unreine Funktion
let obj = { a: 0 }
const impure = (input) => {
// Modifies input.a
input.a = input.a + 1;
return input.a;
}
let b = impure(obj)
console.log(obj) // Logs { "a": 1 }
console.log(b) // Logs 1
Die Funktion hat den Wert für obj.a
geändert, der außerhalb des Gültigkeitsbereichs liegt.
Reine Funktion
let obj = { a: 0 }
const pure = (input) => {
// Does not modify obj
let output = input.a + 1;
return output;
}
let b = pure(obj)
console.log(obj) // Logs { "a": 0 }
console.log(b) // Logs 1
Die Funktion hat die Objektobjektwerte nicht obj
Reine Funktionen dürfen sich nicht auf Variablen außerhalb ihres Gültigkeitsbereichs verlassen
Unreine Funktion
let a = 1;
let impure = (input) => {
// Multiply with variable outside function scope
let output = input * a;
return output;
}
console.log(impure(2)) // Logs 2
a++; // a becomes equal to 2
console.log(impure(2)) // Logs 4
Diese unreine Funktion basiert auf der Variablen a
, die außerhalb ihres Gültigkeitsbereichs definiert ist. Wenn also ein geändert, impure
‚s Funktion Ergebnis wird anders sein.
Reine Funktion
let pure = (input) => {
let a = 1;
// Multiply with variable inside function scope
let output = input * a;
return output;
}
console.log(pure(2)) // Logs 2
Das Funktionsergebnis des pure
ist nicht auf eine Variable außerhalb seines Gültigkeitsbereichs angewiesen .