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:

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 .



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow