function expression

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

We’d love to hear your thoughts on the next set of proposals for the JavaScript language. You can find a description of the proposals here.
Please take two minutes to fill out our short survey.

Das function-Schlüsselwort kann verwendet werden, um eine Funktion innerhalb eines Ausdrucks zu definieren.

Sie können Funktionen auch mithilfe der function-Deklaration oder der Pfeilsyntax definieren.

Probieren Sie es aus

const getRectArea = function (width, height) {
  return width * height;
};

console.log(getRectArea(3, 4));
// Expected output: 12

Syntax

js
function (param0) {
  statements
}
function (param0, param1) {
  statements
}
function (param0, param1, /* …, */ paramN) {
  statements
}

function name(param0) {
  statements
}
function name(param0, param1) {
  statements
}
function name(param0, param1, /* …, */ paramN) {
  statements
}

Hinweis: Eine Ausdrucksanweisung kann nicht mit dem Schlüsselwort function beginnen, um Verwechslungen mit einer function-Deklaration zu vermeiden. Das function-Schlüsselwort beginnt einen Ausdruck nur dann, wenn es in einem Kontext erscheint, der keine Anweisungen akzeptieren kann.

Parameter

name Optional

Der Funktionsname. Kann weggelassen werden, in diesem Fall ist die Funktion anonym. Der Name ist nur lokal im Funktionskörper verfügbar.

paramN Optional

Der Name eines formalen Parameters für die Funktion. Für die Syntax der Parameter siehe die Funktionsreferenz.

statements Optional

Die Anweisungen, die den Körper der Funktion bilden.

Beschreibung

Ein function-Ausdruck ist einem function-Deklaration sehr ähnlich und hat fast dieselbe Syntax. Der Hauptunterschied zwischen einem function-Ausdruck und einer function-Deklaration ist der Funktionsname, der in function-Ausdrücken weggelassen werden kann, um anonyme Funktionen zu erstellen. Ein function-Ausdruck kann als IIFE (Immediately Invoked Function Expression) verwendet werden, die ausgeführt wird, sobald sie definiert ist. Siehe auch das Kapitel über Funktionen für weitere Informationen.

Hoisting von Funktionsausdrücken

Funktionsausdrücke in JavaScript werden nicht gehoben, im Gegensatz zu Funktionsdeklarationen. Sie können Funktionsausdrücke nicht verwenden, bevor Sie sie erstellen:

js
console.log(notHoisted); // undefined
// Even though the variable name is hoisted,
// the definition isn't. so it's undefined.
notHoisted(); // TypeError: notHoisted is not a function

var notHoisted = function () {
  console.log("bar");
};

Benannter Funktionsausdruck

Wenn Sie innerhalb des Funktionskörpers auf die aktuelle Funktion verweisen möchten, müssen Sie einen benannten Funktionsausdruck erstellen. Dieser Name ist dann nur lokal im Funktionskörper (Geltungsbereich) vorhanden. Dies vermeidet die Verwendung der veralteten arguments.callee-Eigenschaft, um die Funktion rekursiv aufzurufen.

js
const math = {
  factorial: function factorial(n) {
    console.log(n);
    if (n <= 1) {
      return 1;
    }
    return n * factorial(n - 1);
  },
};

math.factorial(3); //3;2;1;

Wenn ein Funktionsausdruck benannt ist, wird die name-Eigenschaft der Funktion auf diesen Namen gesetzt, anstatt auf den impliziten Namen, der aus der Syntax abgeleitet wird (wie die Variable, der die Funktion zugewiesen wird).

Im Gegensatz zu Deklarationen ist der Name von Funktionsausdrücken schreibgeschützt.

js
"use strict";

function foo() {
  foo = 1;
}
foo();
console.log(foo); // 1
(function foo() {
  foo = 1; // TypeError: Assignment to constant variable.
})();

Beispiele

Verwendung des Funktionsausdrucks

Im folgenden Beispiel wird eine unbenannte Funktion definiert und x zugewiesen. Die Funktion gibt das Quadrat ihres Arguments zurück:

js
const x = function (y) {
  return y * y;
};

Verwendung einer Funktion als Callback

Häufiger wird sie als Callback verwendet:

js
button.addEventListener("click", function (event) {
  console.log("button is clicked!");
});

Verwendung eines Immediately Invoked Function Expression (IIFE)

IIFEs sind ein häufiges Muster, das verwendet wird, um beliebig viele Anweisungen in ihrem eigenen Geltungsbereich auszuführen (und möglicherweise einen Wert zurückzugeben) an einem Ort, der einen einzigen Ausdruck erfordert. Viele traditionelle Anwendungsfälle von IIFEs wurden durch neue Syntaxmerkmale wie Module und blockgebundene Deklarationen überflüssig gemacht. IIFEs werden jetzt häufiger mit Pfeilfunktionen geschrieben, aber die Idee bleibt dieselbe. Im Allgemeinen sehen IIFEs so aus:

js
// standard IIFE
(function () {
  // statements…
})();

// IIFE with arguments
(function (a, b) {
  console.log(a + b);
})(1, 2); // logs 3

// IIFE being used to initialize a variable
const value = (() => {
  const randomValue = Math.random();
  if (randomValue > 0.5) {
    return "heads";
  } else {
    return "tails";
  }
})();

Hier stellen wir mehrere Anwendungsfälle mit Beispielen vor.

Vermeidung der Verschmutzung des globalen Namensraums im Skriptcode

Der oberste Geltungsbereich aller Skripte wird geteilt, was viele Funktionen und globale Variablen aus verschiedenen Dateien umfassen könnte. Um Namenskonflikte zu vermeiden, ist es wichtig, die Anzahl der global deklarierten Namen zu begrenzen (dies wird in Modulen erheblich gemildert, aber manchmal ist es immer noch nützlich, den Geltungsbereich temporärer Variablen zu beschränken, besonders wenn die Datei sehr lang ist). Wenn wir einen Initialisierungscode haben, den wir nicht wieder verwenden müssen, könnten wir das IIFE-Muster verwenden, was besser ist als eine Funktionsdeklaration oder ein Funktionsausdruck, weil es sicherstellt, dass der Code nur hier und einmal ausgeführt wird.

js
// top-level of a script (not a module)

var globalVariable = (() => {
  // some initialization code
  let firstVariable = something();
  let secondVariable = somethingElse();
  return firstVariable + secondVariable;
})();

// firstVariable and secondVariable cannot be accessed outside of the function body.

Das Modul-Muster

Wir verwenden auch IIFE, um private und öffentliche Variablen und Methoden zu erstellen. Für eine anspruchsvollere Verwendung des Modul-Musters und andere Verwendungen von IIFE können Sie das Buch "Learning JavaScript Design Patterns" von Addy Osmani sehen.

js
const makeWithdraw = (balance) =>
  ((copyBalance) => {
    let balance = copyBalance; // This variable is private
    const doBadThings = () => {
      console.log("I will do bad things with your money");
    };
    doBadThings();
    return {
      withdraw(amount) {
        if (balance >= amount) {
          balance -= amount;
          return balance;
        }
        return "Insufficient money";
      },
    };
  })(balance);

const firstAccount = makeWithdraw(100); // "I will do bad things with your money"
console.log(firstAccount.balance); // undefined
console.log(firstAccount.withdraw(20)); // 80
console.log(firstAccount.withdraw(30)); // 50
console.log(firstAccount.doBadThings); // undefined; this method is private
const secondAccount = makeWithdraw(20); // "I will do bad things with your money"
console.log(secondAccount.withdraw(30)); // "Insufficient money"
console.log(secondAccount.withdraw(20)); // 0

For-Schleife mit var vor ES6

Wir könnten die folgende Verwendung von IIFE in altem Code sehen, vor der Einführung der blockgebundenen let- und const-Deklarationen. Mit der Anweisung var haben wir nur Funktionsklammern und den globalen Geltungsbereich. Angenommen, wir möchten 2 Buttons erstellen mit den Texten Button 0 und Button 1 und wenn wir sie anklicken, möchten wir, dass sie 0 bzw. 1 anzeigen. Der folgende Code funktioniert nicht:

js
for (var i = 0; i < 2; i++) {
  const button = document.createElement("button");
  button.innerText = `Button ${i}`;
  button.onclick = function () {
    console.log(i);
  };
  document.body.appendChild(button);
}
console.log(i); // 2

Beim Klick zeigen sowohl Button 0 als auch Button 1 den Wert 2 an, weil i global ist, mit dem letzten Wert 2. Um dieses Problem vor ES6 zu lösen, könnten wir das IIFE-Muster verwenden:

js
for (var i = 0; i < 2; i++) {
  const button = document.createElement("button");
  button.innerText = `Button ${i}`;
  button.onclick = (function (copyOfI) {
    return function () {
      console.log(copyOfI);
    };
  })(i);
  document.body.appendChild(button);
}
console.log(i); // 2

Beim Klick zeigen die Buttons 0 und 1 den Wert 0 bzw. 1 an. Die Variable i ist global definiert. Mit der Anweisung let könnten wir einfach folgendes tun:

js
for (let i = 0; i < 2; i++) {
  const button = document.createElement("button");
  button.innerText = `Button ${i}`;
  button.onclick = function () {
    console.log(i);
  };
  document.body.appendChild(button);
}
console.log(i); // Uncaught ReferenceError: i is not defined.

Beim Klick zeigen diese Buttons 0 bzw. 1 an.

Kontrollflussanweisungen in Ausdruckspositionen

IIFEs ermöglichen es uns, Sprachkonstrukte wie switch in einem Ausdruck zu verwenden.

js
someObject.property = (() => {
  switch (someVariable) {
    case 0:
      return "zero";
    case 1:
      return "one";
    default:
      return "unknown";
  }
})();

Dieser Ansatz kann besonders nützlich sein in Szenarien, in denen Sie eine Variable const machen möchten, aber gezwungen sind, let oder var während der Initialisierung zu verwenden:

js
let onlyAssignedOnce;
try {
  onlyAssignedOnce = someFunctionThatMightThrow();
} catch (e) {
  onlyAssignedOnce = null;
}

Mit IIFEs können wir die Variable const machen:

js
const onlyAssignedOnce = (() => {
  try {
    return someFunctionThatMightThrow();
  } catch (e) {
    return null;
  }
})();

Spezifikationen

Specification
ECMAScript® 2026 Language Specification
# sec-function-definitions

Browser-Kompatibilität

Siehe auch