Variationen von Funktionen
Javascript kennt vier, nehmen wir noch die Kurzschreibweise der Arrow-Funktionen hinzu, fünf Schreibweisen für Funktionen
// Funktions-Anweisung oder function statement function foo() { return 5; } // Anonymer Funktions-Ausdruck oder anonymous function expression let foo = function() { return 5; } // Funktions-Ausdruck oder function expression let foo = function foo() { return 5; } // IIFE (Immediately Invoked Function Expression) beginnen mit "(" (function () { return 5; } ()); // Arrow function let foo = (num) => { return 5 }
»Normale« Funktionen
Normale Funktionen (Funktions-Anweisung, Funktions-Deklaration oder function statement), so wie sie Programmierer von vielen Programmiersprachen kennen, folgen einer einfachen Syntax:
- Eine »normale« Funktion beginnt mit dem Schlüsselwort function und muss einen Namen haben,
- kann null oder mehr Parameter in runden Klammern haben,
- der Body wird in geschweifte Klammern gesetzt und enthält null oder mehr Anweisungen.
function brutto (betrag, satz) { const mwst = betrag * satz / 100; return betrag + mwst; } const summe = brutto (400, 19); console.log ("summe", summe); // summe – 476
Funktion einer Variablen zuweisen
In Javascript lassen sich Funktionen auch anders definieren. Wenn das Ergebnis einer Funktion direkt einer Variablen zugewiesen wird, haben wir einen Funktions-Ausdruck oder Function Expression.
const summe = function (betrag, satz) { const mwst = betrag * satz / 100; return betrag + mwst; }; console.log ("summe", summe(400, 19)); // summe – 476
In Javascript wird kein Semikolon an das Ende einer Funktions-Deklaration gesetzt, wohl aber an das Ende des Funktionsausdrucks.
Auf den ersten Blick scheint der Unterschied zwischen einer Funktions-Anweisung und einem Funktionsausdruck eher homöopathischer Natur zu sein, aber ein Funktions-Ausdruck muss keinen Namen haben.
kein Name ---┐ ▼ const summe = function (betrag, satz) { const mwst = betrag * satz / 100; return betrag + mwst; }; console.log ("summe", summe (400,19)); // summe – 476
Am Ende gibt es noch einen Unterschied: Bei einer normalen Funktion kann der Funktionsaufruf vor der Deklaration der Funktion stehen.
const summe = brutto (400, 19); function brutto (betrag, satz) { const mwst = betrag * satz / 100; return betrag + mwst; }
Der Aufruf einer function expression kann nicht vor der Deklaration des Funktionsausdrucks stehen. Das würde zu einem Fehler führen.
console.log ("summe", summe (400,19));
// [Error] ReferenceError: Cannot access uninitialized variable.
const summe = function (betrag, satz) {
const mwst = betrag * satz / 100;
return betrag + mwst;
};
Javascript-Funktionen müssen keinen Namen haben
Hat die Funktion einen Namen, kann sie erneut aufgerufen werden, was nicht immer wünschenswert ist. Diese Form der anonymen Funktion stellt sicher, dass sie nur einmal ausgeführt werden kann.
Funktions-Ausdrücke können anonym sein oder einen Namen haben.
// Anonymer Funktions-Ausdruck let a = function() { return 3; } // Funktions-Ausdruck mit Namen let a = function foo() { return 3; } // Selbstaufrufender Funktions-Ausdruck (function sagWas() { alert("Hallo!"); })();
Auf jeden Fall: Der Name der Funktion – wenn sie überhaupt einen Namen hat – ist außerhalb ihres Scopes (Geltungsbereich) nicht sichtbar.
Auswertung von Funktionsausdrücken
Die einfache Funktions-Anweisung function foo () { … } war zuerst da. Der Funktions-Ausdruck kam erst später dazu. Die Funktions-Anweisung ist tatsächlich die Kurzschreibweise für die Deklaration einer Variablen und die Zuweisung eines Wert (dem Rückgabewert der Funktion).
Hinter den Kulissen wird zur Laufzeit aus
function foo() {}
let foo = function foo () {};
Hinter den Kulissen der fast identischen Schreibweisen:
- Der Browser lädt Funktions-Anweisungen (function myfunc() { … }), bevor das Script ausgeführt wird.
- Funktions-Ausdrücke (let myVal = function() { … }) werden erst geladen, wenn der Interpreter die entsprechende Zeile im Script anspricht.
- Wenn Funktionen als Funktions-Ausdruck geschrieben werden, kann sie erst aufgerufen werden, nachdem der Funktions-Ausdruck definiert wurde.
alert(foo()); // Wirft einen Fehler!
let foo = function() { return 5; }
Eine banale Regel, um Funktions-Anweisungen von Funktions-Ausdrücken zu unterscheiden ist:
Wenn das erste Wort function ist, dann ist es eine Funktions-Anweisung, sonst ist es ein Funktions-Ausdruck.
Ein Funktions-Ausdruck oder Function Expression erzeugt eine Instanz eines Funktions-Objekts.
Funktionen als Objekte erben von Function.prototype.