Skip to content

Introduction to Functions

Eine Funktion ist ein Codeblock, der Aufgaben in einer bestimmten Reihenfolge ausführt. Eine Funktion gibt explizit oder implizit einen Wert zurück.

Eine Funktion wird mit dem Keyword function deklariert, gefolgt vom Namen der Funktion und einer Klammer. Der Name sollte bestmöglich beschreiben, was die Funktion macht.
Die Funktion wird später mit ihrem Namen aufgerufen (= ausgeführt).

// function declaration
function functionName() {
// do stuff here
}
// function call
functionName();

Funktionen können Parameter annehmen. Parameter sind Platzhalter für Werte, die später an die Funktion übergeben werden. Diese Werte werden in der Funktion verarbeitet.
Die tatsächlichen Werte, die an die Funktion übergeben werden, nennt man Argumente.
Parameter und Argumente werden in die Klammer hinter dem Namen der Funktion notiert und, falls es mehrere sind, mit Beistrichen getrennt.

// function declaration
function functionName(param1, param2) {
// do stuff here with param1 and param2
}
// function call
functionName(arg1, arg2);

Funktionen können (müssen aber nicht) das Keyword return enthalten. return beinhaltet immer auch einen Wert. Wenn die Funktion in ihrem Codeblock ein return findet, wird der Wert, der mit dem return Keyword verbunden ist, an den Code, der die Funktion aufgerufen hat, zurückgegeben und die weitere Ausführung gestoppt.

function multiply(num1, num2) {
return num1 * num2;
}

Hier würde also das Ergebnis der Berechnung von num1 * num2 zurückgegeben.

Würde nach dem return Keyword und der Berechnung noch weiterer Code folgen, würde dieser einfach ignoriert werden. Diese Tatsache kann man sich auch zunutze machen und im control flow einen Wert bald zurückgeben. Das macht man in zwei Situationen:

  1. um verschachtelten Code zu reduzieren
  2. um else if Statements zu vermeiden

1. Reducing nested code
Wenn wir das event delegation pattern benutzen, suchen wir in der Regel nach einem bestimmten Element, und wenn dieses Element vorhanden ist, führen wir einen bestimmten Code aus.

container.addEventListener('click', e => {
const el = e.target.closest('.some-element');
if (el) {
// do stuff here
}
});

Mit einem early return wird die Schreibweise klarer (wir brauchen den Code nicht verschachteln):

container.addEventListener('click', e => {
const el = e.target.closest('.some-element');
if (!el) {
return;
}
// do stuff here
})

2. Removing else if statements
Ein else if Statement benutzen wir, wenn wir eine Kontrollstruktur brauchen, die drei oder mehr Codeblocks ausführen kann.

let gift;
if (score === 100) {
gift = 'Xbox';
} else if (score > 75) {
gift = 'new phone';
} else if (score > 50) {
gift = 'a meal';
} else {
gift = null;
}

if/else ist mühsam, else if ist noch mühsamer. Wir können die Prozedur mit einer Funktion abkürzen und return nutzen:

function getGift(score) {
if (score === 100) {
return 'Xbox';
}
if (score > 75) {
return 'new phone';
}
if (score > 50) {
return 'a meal';
}
return null;
}
let score = getGift(100);
// wenn nur ein Ausdruck im Codeblock steht, kann man auf die curly brackets verzichten:
function getGift(score) {
if (score === 100) return 'Xbox';
if (score > 75) return 'new phone';
if (score > 50) return 'a meal';
return null;
}

Wenn JavaScript kein return Statement findet, wird undefined zurückgegeben.
Wenn der Wert ein Ausdruck ist, wird dieser ausgewertet und der ausgewertete Wert zurückgegeben.

Funktionen, die mit dem Keyword function deklariert wurden, werden automatisch an den Anfang des Scripts verschoben. So könnte man sie theoretisch am Ende der Seite unterbringen. JavaScript sorgt dafür, dass sie vorher schon verfügbar sind.

Ein Funktionsausdruck bedeutet, dass eine Funktion “manuell” deklariert wird (also ohne das Keyword function) und der Wert der Funktion sofort einer Variablen zugewiesen wird.
Diese Funktion benötigt keinen Namen (da sie ja durch die Variabe nutzbar wird). Entsprechend wird die Funktion auch nicht mit dem Namen der Funktion aufgerufen (den es ja gar nicht gibt), sondern mit dem Namen der Variablen, der die Funktion zugewiesen wurde.

const functionExpression = function (param1, param2) {
// do stuff here with param1 and param2
};
// function call:
functionExpression(arg1, arg2);

Funktionsausdrücke werden hauptsächlich in Arrow Functions verwendet.

Arrow functions machen Programmcode kürzer und übersichtlicher – und damit weniger fehleranfällig (obwohl sie ein bisschen einschüchernd aussehen).
Die Basis einer Arrow Function bildet ein Funktionsausdruck bzw. eine anonyme Funktion, mit zwei Unterschieden:

  • Das Keyword function entfällt
  • Zwischen den Parametern und der geschwungenen Klammer wird ein Arrow => eingefügt.

Der Funktionsaufruf erfolgt – wie bei anonymen Funktionen üblich – nicht mit dem Namen der Funktion, sondern mit dem Namen der Variablen, der die Funktion zugewiesen wird.

const arrowFunction = (param1, param2) => {
// do stuff here with param1 and param2
};
// function call:
arrowFunction(arg1, arg2);

Je nach Anzahl der Parameter und der gewünschten Rückgabemethode (implicit or explicit return, siehe unten) können Arrow Functions auf verschiedene Arten geschrieben werden:

// one argument: common syntax with parenthesis
const oneArgParenthesis = (param1) => {
// do stuff here
};
// with just one argument, you can remove the parenthesis
const oneArgNoParenthesis = param1 => {
// do stuff here
};
// zero arguments: common syntax with parenthesis (empty)
const zeroArgsParenthesis = () => {
// do stuff here
};
// zero arguments, parenthesis replaced with underscore
const zeroArgsUnderscore = _ => {
// do stuff here
};

Arrow functions erzeugen das return Statement automatisch, wenn

  • der Code in einer Zeile steht
  • die Codezeile nicht in geschwungenen Klammern steht
// normal function, explicit return
const sumNormal = function (num1, num2) {
return num1 + num2;
};
// implicit return
const sumArrow = (num1, num2) => num1 + num2;

Wenn man ein Objekt als Rückgabewert benötigt, kann man die geschwungenen Klammern in normale Klammern setzen, um ein implicit return zu triggern. (Ohne normale Klammern würde JavaScript die geschwungenen Klammern als Codeblock interpretieren, und das funktioniert dann gar nicht.)

// returning an object (explicit)
const functionName = _ => {
return {
key: 'value',
};
};
// implicit
const functionName = _ => ({ key: 'value' });

Wann nimmt man was?
Wenn es Sinn macht, eine Funktion zu benennen und auszulagern, nimmt man eine Funktionsdeklaration.
Arrow functions nimmt man, wenn man anonyme Funktionen benötigt (meistens bei Callbacks in Event Listenern).