Kategorien
JavaScript

Funktionale Programmierung mit JavaScript

JavaScript ist keine funktionale Programmiersprache, aber die wichtigsten Prinzipien der funktionalen Programmierung lassen sich trotzdem beim Programmieren an einigen Stellen anwenden.

Diese Prinzipien sind u.a.:

  1. Funktionen haben Inputs und Outputs, aber keine Nebenwirkungen. Sie bearbeiten keine Daten, die ihnen nicht explizit übergeben wurden
  2. Variablen werden nicht verändert (Immortabilität)
  3. Funktionen höherer Ordnung dienen zur Schachtelung von Funktionen. Als Input (Parameter) von Funktionen werden wiederum Funktionen verwendet

An den folgende Beispielen und sehr praktischen Array Methoden soll der Unterschied zwischen funktionaler und nicht funktionaler Programmierung gezeigt werden:

forEach

Die Array methode forEach ermöglicht es funktional über ein Array zu iterieren, ohne eine sich verändernde Variable i zu verwenden.

// Beispiel alle Einträge in companies auf der Konsole ausgeben

//nicht funktional
for(let i = 0; i < companies.length; i++) {
   console.log(companies[i]);
}

//funktional
companies.forEach(function(company) {
  console.log(company);
});

filter

Die Array Methode filter entfernt Einträge aus einem Array, die nicht der übergebenen Bedingung entsprechen und gibt diese zurück. Man beachte, dass das ursprüngliche Array nicht verändert wird und die filter Mezhode selbst ein Funktion höherer Ordnung ist, weil als Parameter eine Funktion übergeben wird.

//Beispiel: alle Zahlen über 21 herausfiltern
const ages = [13, 15, 45, 25, 64, 32];

// nicht funktional
let canDrink = [];
for(let i = 0; i < ages.length; i++) {
  if(ages[i] >= 21) {
    canDrink.push(ages[i]);
  }
}

// funktional
const canDrink = ages.filter(function(age) {
  if(age >= 21) {
    return true;
  }
});

map

Mit map kann auf jedes Element eines Arrays eine Funktion angewendet werden.

//Beispiel: Ein Array mit allen Company Namen erstellen
const companies= [
  {name: "Company One", category: "Finance"},
  {name: "Company Two", category: "Retail"},
];

//nicht funktional
let companyNames = []
for(let i = 0; i < companies.length; i++) {
   companyNames.push(companies[i].name);
}


// funktional
const companyNames = companies.map(function(company) {
  return company.name;
});

// oder noch kürzer mit der Arrow Funktion https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Functions/Arrow_functions
const companyNames = companies.map(company => company.name);

reduce

Die reduce Methode reduziert ein Array auf einen einzigen Wert, indem es jeweils zwei Elemente (von links nach rechts) durch eine gegebene Funktion vereinfacht.

//Beispiel: Berechnen der Summe aller Einträge in ages
const ages = [13, 15, 45, 25, 64, 32];

// nicht funktional
let ageSum = 0;
for(let i = 0; i < ages.length; i++) {
  ageSum += ages[i];
}

//funktional
const ageSum = ages.reduce(function(total, age) {
  return total + age;
}, 0);

// oder funktional mit der Arrow Funktion
const ageSum = ages.reduce((total, age) => total + age, 0);

Hinweis: Der zweite Parameter „0“ ist der Startwert von total in dem Beispiel.

sort

Mit sort lässt sich ein Array nach beliebigen Kriterien mittels einer Sortierfunktion sortieren.

Die Sortierfunktion hat 2 Parameter a und b und gibt eine Zahl zurück. Wobei a und b Elemente des Arrays sind.

// Syntax der Sortierfunktion
function compare(a, b) {
  if (a ist kleiner als b anhand von Sortierkriterien) {
    return -1;
  }
  if (a ist größer als b anhand der Sortierkriterien) {
    return 1;
  }
  // a muss gleich b sein
  return 0;
}
//Beispiel: sortieren nach Alter von klein nach groß
const ages = [13, 45, 25];

const sortAges = companies.ages(function(a, b) {
  if(a < b) {
    return -1;
  } else {
    return 1;
  }
});

const sortAges = ages.sort((a, b) => a - b);
// ergibt [13, 25, 45];

kombinieren / aneinanderreihen der Funktionen

Alle Funktionen lassen sich elegant miteinader kombinieren (Chaining):

const combined = ages.map(age => age * 2)
.filter(age => age >= 40)
.sort((a, b) => a - b)
.reduce((a, b) => a + b, 0);