Javascript Function Expression / Funktions-Ausdruck

Javascript function expression: Funktionen ohne Namen, namenslos, noname

Ein Funktions-Ausdruck oder function expression sieht fast so aus wie eine normale Funktion, aber kann direkt einer Variablen zugewiesen werden. Vor allem ist ein Funktions-Ausdruck außerhalb seines Scopes oder Gültigkeitsbereichs nicht sichtbar – die Javascript-Version von private.

23-02-02 SITEMAP CSS HTML JS Basis JS Web Tutorial SVG

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:

  1. Eine »normale« Funktion beginnt mit dem Schlüsselwort function und muss einen Namen haben,
  2. kann null oder mehr Parameter in runden Klammern haben,
  3. 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:

  1. Der Browser lädt Funktions-Anweisungen (function myfunc() { … }), bevor das Script ausgeführt wird.
  2. Funktions-Ausdrücke (let myVal = function() { … }) werden erst geladen, wenn der Interpreter die entsprechende Zeile im Script anspricht.
  3. 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; }
TypeError: foo is not a function. (In 'foo()', 'foo' is undefined)

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.