Javascript Function Expression / Funktionsausdruck
Ein Funktionsausdruck oder function expression sieht fast so aus wie eine normale Funktion, aber kann direkt einer Variablen zugewiesen werden. Vor allem ist ein Funktionsausdruck außerhalb seines Scopes oder Gültigkeitsbereichs nicht sichtbar – die Javascript-Version von private.
Variationen von Funktionen
Javascript kennt vier, nehmen wir noch die Kurzschreibweise der Arrow-Funktionen hinzu, fünf Schreibweisen für Funktionen.
// Function Declarations ( Funktionsdeklaration function foo() { return 5; } // Anonymer Funktionsausdruck oder anonymous function expression const foo = function() { return 5; } // Funktionsausdruck oder function expression const foo = function foo() { return 5; } // IIFE (Immediately Invoked Function Expression) beginnen mit "(" (function () { return 5; } ()); // Arrow function const foo = (num) => { return 5 }
»Normale« Funktionen
Normale Funktionen (Funktionsdeklaration), 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
Function Expression: 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 Funktionsausdruck 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 Funktionsdeklaration gesetzt, wohl aber an das Ende des Funktionsausdrucks.
Auf den ersten Blick scheint der Unterschied zwischen einer Funktionsanweisung und einem Funktionsausdruck eher homöopathischer Natur zu sein, aber ein Funktionsausdruck 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.
Funktionsausdrücke können anonym sein oder einen Namen haben.
// Anonymer Funktionsausdruck
let a = function() {
return 3;
}
// Funktionsausdruck mit Namen
let a = function foo() {
return 3;
}
// Selbstaufrufender Funktionsausdruck
(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 Funktionsanweisung function foo () { … } war zuerst da. Der Funktionsausdruck 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() {}
const foo = function foo () {};
Hinter den Kulissen der fast identischen Schreibweisen:
- Der Browser lädt Funktionsanweisungen (function myfunc() { … }), bevor das Script ausgeführt wird.
- Funktionsausdrücke (let myVal = function() { … }) werden erst geladen, wenn der Interpreter die entsprechende Zeile im Script anspricht.
- Wenn Funktionen als Funktionsausdruck geschrieben werden, kann sie erst aufgerufen werden, nachdem der Funktionsausdruck definiert wurde.
alert(foo()); // Wirft einen Fehler!
const foo = function() { return 5; }
Eine banale Regel, um Funktionsanweisungen von Funktionsausdrücken zu unterscheiden, ist:
Wenn das erste Wort function ist, dann ist es eine Funktionsanweisung, sonst ist es ein Funktionsausdruck.
Ein Funktionsausdruck oder Function Expression erzeugt eine Instanz eines Funktions-Objekts.
Funktionen als Objekte erben von Function.prototype.