Default parameters
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.
Standard-Parameter von Funktionen erlauben es, benannte Parameter mit Standardwerten zu initialisieren, falls kein Wert oder undefined
übergeben wird.
Probieren Sie es aus
Syntax
function fnName(param1 = defaultValue1, /* …, */ paramN = defaultValueN) {
// …
}
Beschreibung
In JavaScript sind Funktionsparameter standardmäßig auf undefined
gesetzt. Es ist jedoch oft nützlich, einen anderen Standardwert zu definieren. Hier können Standard-Parameter helfen.
Im folgenden Beispiel, falls kein Wert für b
bereitgestellt wird, wenn multiply
aufgerufen wird, wäre der Wert von b
undefined
bei der Bewertung von a * b
und multiply
würde NaN
zurückgeben.
function multiply(a, b) {
return a * b;
}
multiply(5, 2); // 10
multiply(5); // NaN !
In der Vergangenheit bestand die allgemeine Strategie zur Festlegung von Standardwerten darin, Parameterwerte im Funktionskörper zu überprüfen und einen Wert zuzuweisen, falls sie undefined
sind. Im folgenden Beispiel wird b
auf 1
gesetzt, wenn multiply
mit nur einem Argument aufgerufen wird:
function multiply(a, b) {
b = typeof b !== "undefined" ? b : 1;
return a * b;
}
multiply(5, 2); // 10
multiply(5); // 5
Mit Standard-Parametern sind solche Überprüfungen im Funktionskörper nicht mehr notwendig. Jetzt können Sie 1
als Standardwert für b
im Funktionskopf zuweisen:
function multiply(a, b = 1) {
return a * b;
}
multiply(5, 2); // 10
multiply(5); // 5
multiply(5, undefined); // 5
Parameter werden immer noch von links nach rechts gesetzt und überschreiben Standard-Parameter, auch wenn es spätere Parameter ohne Standardwerte gibt.
function f(x = 1, y) {
return [x, y];
}
f(); // [1, undefined]
f(2); // [2, undefined]
Hinweis:
Der erste Standard-Parameter und alle Parameter danach tragen nicht zur length
der Funktion bei.
Die Initialisierungen der Standard-Parameter leben in ihrem eigenen Scope, der über dem Scope liegt, der für den Funktionskörper erstellt wird.
Das bedeutet, dass frühere Parameter in den Initialisierungen späterer Parameter referenziert werden können. Funktionen und Variablen, die im Funktionskörper deklariert sind, können jedoch von den Initialisierungen der Standard-Parameter nicht referenziert werden. Ein Versuch dies zu tun, führt zu einem Laufzeit-ReferenceError
. Dies schließt auch mit var
deklarierte Variablen im Funktionskörper ein.
Zum Beispiel wird die folgende Funktion beim Aufruf einen ReferenceError
werfen, da der Standard-Parameterwert keinen Zugriff auf den Kind-Scope des Funktionskörpers hat:
function f(a = go()) {
function go() {
return ":P";
}
}
f(); // ReferenceError: go is not defined
Diese Funktion wird den Wert des Parameters a
ausgeben, da die Variable var a
nur an die Spitze des Scopes gehostet wird, der für den Funktionskörper erstellt wird, nicht jedoch den übergeordneten Scope, der für die Parameterliste erstellt wird, sodass ihr Wert für b
nicht sichtbar ist.
function f(a, b = () => console.log(a)) {
var a = 1;
b();
}
f(); // undefined
f(5); // 5
Standard-Parameter erlauben jeden Ausdruck, aber Sie können nicht await
oder yield
verwenden, die die Auswertung des Standardausdrucks pausieren würden. Der Parameter muss synchron initialisiert werden.
async function f(a = await Promise.resolve(1)) {
return a;
}
Hinweis:
Da der Standard-Parameter ausgewertet wird, wenn die Funktion aufgerufen wird und nicht, wenn die Funktion definiert wird, hängt die Gültigkeit der await
- und yield
-Operatoren von der Funktion selbst ab, nicht von ihrer umgebenden Funktion. Zum Beispiel wird await
als Bezeichner geparst und folgt den normalen Bezeichnersyntaxregeln, selbst wenn diese Funktion in einer async
Funktion genestet ist.
Beispiele
Übergabe von undefined vs. anderen falsy Werten
Im zweiten Aufruf in diesem Beispiel, selbst wenn das erste Argument explizit auf undefined
gesetzt wird (jedoch nicht null
oder andere falsy Werte), bleibt der Wert des num
-Arguments der Standardwert.
function test(num = 1) {
console.log(typeof num);
}
test(); // 'number' (num is set to 1)
test(undefined); // 'number' (num is set to 1 too)
// test with other falsy values:
test(""); // 'string' (num is set to '')
test(null); // 'object' (num is set to null)
Auswertung zur Aufrufzeit
Das Standard-Argument wird zur Aufrufzeit ausgewertet. Anders als bei Python (zum Beispiel) wird jedes Mal, wenn die Funktion aufgerufen wird, ein neues Objekt erstellt.
function append(value, array = []) {
array.push(value);
return array;
}
append(1); // [1]
append(2); // [2], not [1, 2]
Das gilt auch für Funktionen und Variablen:
function callSomething(thing = something()) {
return thing;
}
let numberOfTimesCalled = 0;
function something() {
numberOfTimesCalled += 1;
return numberOfTimesCalled;
}
callSomething(); // 1
callSomething(); // 2
Frühere Parameter sind für spätere Standard-Parameter verfügbar
Frühere (linksstehende) Parameter sind für spätere Standard-Parameter verfügbar:
function greet(name, greeting, message = `${greeting} ${name}`) {
return [name, greeting, message];
}
greet("David", "Hi"); // ["David", "Hi", "Hi David"]
greet("David", "Hi", "Happy Birthday!"); // ["David", "Hi", "Happy Birthday!"]
Diese Funktionalität kann so näherungsweise nachgebildet werden, was veranschaulicht, wie viele Randfälle behandelt werden:
function go() {
return ":P";
}
function withDefaults(
a,
b = 5,
c = b,
d = go(),
e = this,
f = arguments,
g = this.value,
) {
return [a, b, c, d, e, f, g];
}
function withoutDefaults(a, b, c, d, e, f, g) {
switch (arguments.length) {
case 0:
case 1:
b = 5;
case 2:
c = b;
case 3:
d = go();
case 4:
e = this;
case 5:
f = arguments;
case 6:
g = this.value;
}
return [a, b, c, d, e, f, g];
}
withDefaults.call({ value: "=^_^=" });
// [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="]
withoutDefaults.call({ value: "=^_^=" });
// [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="]
Destrukturierter Parameter mit Zuweisung des Standardwerts
Sie können die Zuweisung eines Standardwerts mit der destructuring assignment-Syntax verwenden.
Eine übliche Methode, dies zu tun, ist es, ein leeres Objekt/Array als Standardwert für den destrukturierten Parameter zu setzen; zum Beispiel: [x = 1, y = 2] = []
. Dadurch ist es möglich, nichts an die Funktion zu übergeben und dennoch diese Werte vorab zu füllen:
function preFilledArray([x = 1, y = 2] = []) {
return x + y;
}
preFilledArray(); // 3
preFilledArray([]); // 3
preFilledArray([2]); // 4
preFilledArray([2, 3]); // 5
// Works the same for objects:
function preFilledObject({ z = 3 } = {}) {
return z;
}
preFilledObject(); // 3
preFilledObject({}); // 3
preFilledObject({ z: 2 }); // 2
Spezifikationen
Specification |
---|
ECMAScript Language Specification # sec-function-definitions |
Browser-Kompatibilität
BCD tables only load in the browser