Signatur
Beschreibung
In JavaScript sind Funktionen Objekte erster Klasse: Jede Funktion, egal ob Funktionsdeklaration, Funktionsausdruck, Pfeilfunktion, Methode oder Klasse, ist eine Instanz von Function. Deshalb ergibt (() => {}) instanceof Function den Wert true. Außerdem kann man Funktionen Eigenschaften zuweisen, sie als Argumente übergeben und aus anderen Funktionen zurückgeben.
Über Function.prototype erben alle Funktionen die Methoden call(), apply() und bind(), mit denen sich der this-Wert und die Argumente steuern lassen. Dazu kommen toString(), das den Quelltext liefert, und [Symbol.hasInstance](), das bestimmt, wie instanceof arbeitet. Die Instanzeigenschaften length (Anzahl der deklarierten Parameter vor dem ersten Standardwert bzw. Rest-Parameter) und name (Name der Funktion) sind schreibgeschützt, lassen sich aber per Object.defineProperty() neu konfigurieren. Konstruierbare Funktionen haben zusätzlich eine eigene Eigenschaft prototype.
Mit dem Konstruktor new Function(arg1, …, argN, functionBody) (oder ohne new) lassen sich Funktionen zur Laufzeit aus Strings erzeugen. Anders als bei eval() läuft der erzeugte Code immer im globalen Scope: Er sieht keine lokalen Variablen der Umgebung, in der er erzeugt wurde. In der Praxis braucht man das selten, etwa für Template-Engines oder Ausdrucks-Rechner. Für normalen Code nimmt man Funktionsdeklarationen oder Pfeilfunktionen.
Verwandte Konstruktoren gibt es auch für asynchrone Funktionen und Generatorfunktionen (AsyncFunction, GeneratorFunction, AsyncGeneratorFunction). Sie sind keine globalen Variablen, man erreicht sie z. B. über Object.getPrototypeOf(async () => {}).constructor.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $arg1, …, argN | string | Namen der formalen Parameter als Strings. Man kann auch mehrere Namen in einem String kommagetrennt angeben ("a, b"). Standardwerte und Rest-Parameter ("...rest") sind erlaubt. |
|
| $functionBody | string | "" | Der Funktionsrumpf als String mit JavaScript-Anweisungen. Wird als letztes Argument erwartet. Fehlt er, entsteht eine leere Funktion. |
Rückgabewert
Function(...) und new Function(...) verhalten sich gleich.Beispiele
Funktionen sind Objekte: Eigenschaften und instanceof
const greet = (name, greeting = 'Hallo') => `${greeting}, ${name}!`;
console.log(greet instanceof Function); // jede Funktion ist ein Function-Objekt
console.log(typeof greet);
console.log(greet.name); // abgeleiteter Name
console.log(greet.length); // zählt nur Parameter ohne Standardwert
// Funktionen können eigene Eigenschaften tragen
function counter() {
counter.calls = (counter.calls ?? 0) + 1;
return counter.calls;
}
counter();
counter();
console.log(counter.calls);
this steuern mit call, apply und bind
const user = { name: 'Anna' };
function introduce(city, country) {
return `${this.name} wohnt in ${city}, ${country}.`;
}
console.log(introduce.call(user, 'Berlin', 'DE'));
console.log(introduce.apply(user, ['Wien', 'AT']));
// bind erzeugt eine neue Funktion mit festem this und vorbelegten Argumenten
const introduceAnnaInSwiss = introduce.bind(user, 'Zürich');
console.log(introduceAnnaInSwiss('CH'));
console.log(introduceAnnaInSwiss.name);
Dynamische Funktion mit dem Function-Konstruktor
// Einfacher Formel-Rechner – nur mit vertrauenswürdigen Eingaben verwenden!
const makeFormula = (params, expression) => new Function(...params, `return (${expression});`);
const area = makeFormula(['width', 'height'], 'width * height');
console.log(area(4, 5));
console.log(area.length);
// Globaler Scope: lokale Variablen sind nicht sichtbar
const x = 'lokal';
const test = () => {
const x = 'innen';
return new Function('return typeof x;')();
};
console.log(test());
Konstruktoren für async- und Generatorfunktionen
const AsyncFunction = Object.getPrototypeOf(async () => {}).constructor;
const GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor;
const fetchLater = new AsyncFunction('ms', 'await new Promise(r => setTimeout(r, ms)); return "fertig";');
const range = new GeneratorFunction('n', 'for (let i = 0; i < n; i++) yield i;');
console.log([...range(3)]);
fetchLater(100).then(console.log);
console.log(fetchLater instanceof Function);
// Wichtig · Fallstricke
- Sicherheit: Der
Function-Konstruktor führt beliebigen Code aus Strings aus und ist damit genauso anfällig für Code-Injection/XSS wieeval(). Übergib niemals Nutzereingaben, URL-Parameter oder Serverdaten ohne strenge Prüfung. Eine Content Security Policy ohne'unsafe-eval'blockiertnew Function()(es wird einEvalErrorgeworfen). Auch Chrome-Erweiterungen und viele Hosting-Umgebungen verbieten es. - Kein Zugriff auf Closures: Dynamisch erzeugte Funktionen sehen nur globale Variablen. In ES-Modulen sind also auch Variablen auf Modulebene nicht sichtbar.
- Performance: Der Code-String wird bei jedem Aufruf des Konstruktors neu geparst. Erzeuge die Funktion daher einmal und verwende sie wieder, statt sie in Schleifen neu zu bauen.
- Veraltet:
Function.prototype.argumentsundFunction.prototype.callersind nicht standardisiert und veraltet. In strict-, Pfeil-, async- und Generatorfunktionen wirft der Zugriff einenTypeError. Nutze stattdessen Rest-Parameter (...args) bzw. Stacktraces übernew Error().stack. - Pfeilfunktionen: Sie haben kein eigenes
thisund keineprototype-Eigenschaft, undcall/apply/bindkönnen ihrthisnicht ändern. Mitnewaufgerufen werfen sie einenTypeError. Function.prototypeist selbst eine (leere) Funktion.typeof Function.prototypeergibt daher"function".