JavaScript für ungeduldige Programmierer (ES2022-Ausgabe)
Bitte unterstützen Sie dieses Buch: kaufen Sie es oder spenden Sie
(Werbung, bitte nicht blockieren.)

25 Aufrufbare Werte



In diesem Kapitel betrachten wir JavaScript-Werte, die aufgerufen werden können: Funktionen, Methoden und Klassen.

25.1 Arten von Funktionen

JavaScript hat zwei Kategorien von Funktionen

Lesen Sie weiter, um herauszufinden, was all das bedeutet.

25.2 Gewöhnliche Funktionen

Der folgende Code zeigt zwei Wege, (ungefähr) dasselbe zu tun: eine gewöhnliche Funktion erstellen.

// Function declaration (a statement)
function ordinary1(a, b, c) {
  // ···
}

// const plus anonymous (nameless) function expression
const ordinary2 = function (a, b, c) {
  // ···
};

Innerhalb eines Gültigkeitsbereichs werden Funktionsdeklarationen frühzeitig aktiviert (siehe §11.8 „Deklarationen: Gültigkeitsbereich und Aktivierung“) und können vor ihrer Deklaration aufgerufen werden. Das ist gelegentlich nützlich.

Variablendeklarationen, wie die für ordinary2, werden nicht frühzeitig aktiviert.

25.2.1 Benannte Funktionsausdrücke (fortgeschritten)

Bisher haben wir nur anonyme Funktionsausdrücke gesehen – die keine Namen haben

const anonFuncExpr = function (a, b, c) {
  // ···
};

Aber es gibt auch benannte Funktionsausdrücke

const namedFuncExpr = function myName(a, b, c) {
  // `myName` is only accessible in here
};

myName ist nur innerhalb des Funktionskörpers zugänglich. Die Funktion kann ihn verwenden, um auf sich selbst zu verweisen (für Selbst-Rekursion usw.) – unabhängig davon, welcher Variablen sie zugewiesen ist

const func = function funcExpr() { return funcExpr };
assert.equal(func(), func);

// The name `funcExpr` only exists inside the function body:
assert.throws(() => funcExpr(), ReferenceError);

Selbst wenn sie keinen Variablen zugewiesen sind, haben benannte Funktionsausdrücke Namen (Zeile A)

function getNameOfCallback(callback) {
  return callback.name;
}

assert.equal(
  getNameOfCallback(function () {}), ''); // anonymous

assert.equal(
  getNameOfCallback(function named() {}), 'named'); // (A)

Beachten Sie, dass Funktionen, die über Funktionsdeklarationen oder Variablendeklarationen erstellt werden, immer Namen haben

function funcDecl() {}
assert.equal(
  getNameOfCallback(funcDecl), 'funcDecl');

const funcExpr = function () {};
assert.equal(
  getNameOfCallback(funcExpr), 'funcExpr');

Ein Vorteil von benannten Funktionen ist, dass diese Namen in Fehler-Stack-Traces erscheinen.

25.2.2 Terminologie: Funktionsdefinitionen und Funktionsausdrücke

Eine Funktionsdefinition ist eine Syntax, die Funktionen erstellt

Funktionsdeklarationen erzeugen immer gewöhnliche Funktionen. Funktionsausdrücke erzeugen entweder gewöhnliche Funktionen oder spezialisierte Funktionen

Während Funktionsdeklarationen in JavaScript immer noch beliebt sind, sind Funktionsausdrücke im modernen Code fast immer Pfeilfunktionen.

25.2.3 Teile einer Funktionsdeklaration

Untersuchen wir die Teile einer Funktionsdeklaration anhand des folgenden Beispiels. Die meisten Begriffe gelten auch für Funktionsausdrücke.

function add(x, y) {
  return x + y;
}
25.2.3.1 Nachgestellte Kommas in Parameterlisten

JavaScript hat schon immer nachgestellte Kommas in Array-Literalen erlaubt und ignoriert. Seit ES5 sind sie auch in Objekt-Literalen erlaubt. Seit ES2017 können wir nachgestellte Kommas zu Parameterlisten (Deklarationen und Aufrufen) hinzufügen

// Declaration
function retrieveData(
  contentText,
  keyword,
  {unique, ignoreCase, pageSize}, // trailing comma
) {
  // ···
}

// Invocation
retrieveData(
  '',
  null,
  {ignoreCase: true, pageSize: 10}, // trailing comma
);

25.2.4 Rollen von gewöhnlichen Funktionen

Betrachten Sie die folgende Funktionsdeklaration aus dem vorherigen Abschnitt

function add(x, y) {
  return x + y;
}

Diese Funktionsdeklaration erstellt eine gewöhnliche Funktion mit dem Namen add. Als gewöhnliche Funktion kann add() drei Rollen spielen

25.2.5 Terminologie: Entität vs. Syntax vs. Rolle (fortgeschritten)

Die Unterscheidung zwischen den Konzepten Syntax, Entität und Rolle ist subtil und spielt oft keine Rolle. Aber ich möchte Ihr Auge dafür schärfen

Viele andere Programmiersprachen haben nur eine einzige Entität, die die Rolle echte Funktion spielt. Dann können sie den Namen Funktion für Rolle und Entität verwenden.

25.3 Spezialisierte Funktionen

Spezialisierte Funktionen sind Einzweckversionen von gewöhnlichen Funktionen. Jede von ihnen spezialisiert sich auf eine einzige Rolle

Neben einer schöneren Syntax unterstützt jede Art von spezialisierter Funktion auch neue Features, wodurch sie besser in ihren Aufgaben sind als gewöhnliche Funktionen.

Tabelle 16 listet die Fähigkeiten von gewöhnlichen und spezialisierten Funktionen auf.

Tabelle 16: Fähigkeiten von vier Arten von Funktionen. Wenn ein Zellwert in Klammern steht, impliziert dies eine Art Einschränkung. Die spezielle Variable this wird in §25.3.3 „Die spezielle Variable this in Methoden, gewöhnlichen Funktionen und Pfeilfunktionen“ erklärt.
Funktionsaufruf Methodenaufruf Konstruktoraufruf
Gewöhnliche Funktion (this === undefined)
Pfeilfunktion (lexikalisches this)
Methode (this === undefined)
Klasse

25.3.1 Spezialisierte Funktionen sind immer noch Funktionen

Es ist wichtig zu beachten, dass Pfeilfunktionen, Methoden und Klassen immer noch als Funktionen kategorisiert werden

> (() => {}) instanceof Function
true
> ({ method() {} }.method) instanceof Function
true
> (class SomeClass {}) instanceof Function
true

25.3.2 Pfeilfunktionen

Pfeilfunktionen wurden aus zwei Gründen in JavaScript eingeführt

  1. Um eine prägnantere Möglichkeit zur Erstellung von Funktionen zu bieten.
  2. Sie eignen sich besser als echte Funktionen innerhalb von Methoden: Methoden können über die spezielle Variable this auf das Objekt zugreifen, das einen Methodenaufruf empfangen hat. Pfeilfunktionen können auf das this einer umgebenden Methode zugreifen, gewöhnliche Funktionen können das nicht (weil sie ihr eigenes this haben).

Wir werden zuerst die Syntax von Pfeilfunktionen untersuchen und dann, wie this in verschiedenen Funktionen funktioniert.

25.3.2.1 Die Syntax von Pfeilfunktionen

Lassen Sie uns die Syntax eines anonymen Funktionsausdrucks wiederholen

const f = function (x, y, z) { return 123 };

Die (ungefähr) äquivalente Pfeilfunktion sieht wie folgt aus. Pfeilfunktionen sind Ausdrücke.

const f = (x, y, z) => { return 123 };

Hier ist der Körper der Pfeilfunktion ein Block. Er kann aber auch ein Ausdruck sein. Die folgende Pfeilfunktion funktioniert exakt wie die vorherige.

const f = (x, y, z) => 123;

Wenn eine Pfeilfunktion nur einen einzelnen Parameter hat und dieser Parameter ein Bezeichner ist (kein Destrukturierungsmuster), können Sie die Klammern um den Parameter weglassen

const id = x => x;

Das ist praktisch, wenn Pfeilfunktionen als Parameter an andere Funktionen oder Methoden übergeben werden

> [1,2,3].map(x => x+1)
[ 2, 3, 4 ]

Dieses vorherige Beispiel zeigt einen Vorteil von Pfeilfunktionen – Prägnanz. Wenn wir die gleiche Aufgabe mit einem Funktionsausdruck durchführen, ist unser Code ausführlicher

[1,2,3].map(function (x) { return x+1 });
25.3.2.2 Syntax-Fallstrick: Rückgabe eines Objektliterals aus einer Pfeilfunktion

Wenn der Ausdruckskörper einer Pfeilfunktion ein Objektliteral sein soll, müssen Sie das Literal in Klammern setzen

const func1 = () => ({a: 1});
assert.deepEqual(func1(), { a: 1 });

Wenn Sie das nicht tun, denkt JavaScript, die Pfeilfunktion habe einen Blockkörper (der nichts zurückgibt)

const func2 = () => {a: 1};
assert.deepEqual(func2(), undefined);

{a: 1} wird als Block mit dem Label a: und der Ausdrucksanweisung 1 interpretiert. Ohne eine explizite return-Anweisung gibt der Blockkörper undefined zurück.

Dieser Fallstrick wird durch syntaktische Mehrdeutigkeit verursacht: Objektliterale und Codeblöcke haben die gleiche Syntax. Wir verwenden die Klammern, um JavaScript mitzuteilen, dass der Körper ein Ausdruck (ein Objektliteral) und keine Anweisung (ein Block) ist.

25.3.3 Die spezielle Variable this in Methoden, gewöhnlichen Funktionen und Pfeilfunktionen

  Die spezielle Variable this ist ein objektorientiertes Feature

Wir werfen hier einen kurzen Blick auf die spezielle Variable this, um zu verstehen, warum Pfeilfunktionen bessere echte Funktionen sind als gewöhnliche Funktionen.

Aber dieses Feature ist nur in der objektorientierten Programmierung wichtig und wird ausführlicher in §28.5 „Methoden und die spezielle Variable this behandelt. Machen Sie sich daher keine Sorgen, wenn Sie es noch nicht vollständig verstehen.

Innerhalb von Methoden ermöglicht uns die spezielle Variable this den Zugriff auf den Empfänger – das Objekt, das den Methodenaufruf erhalten hat

const obj = {
  myMethod() {
    assert.equal(this, obj);
  }
};
obj.myMethod();

Gewöhnliche Funktionen können Methoden sein und haben daher auch den impliziten Parameter this

const obj = {
  myMethod: function () {
    assert.equal(this, obj);
  }
};
obj.myMethod();

this ist sogar ein impliziter Parameter, wenn wir eine gewöhnliche Funktion als echte Funktion verwenden. Dann ist ihr Wert undefined (wenn Strict Mode aktiv ist, was fast immer der Fall ist)

function ordinaryFunc() {
  assert.equal(this, undefined);
}
ordinaryFunc();

Das bedeutet, dass eine gewöhnliche Funktion, die als echte Funktion verwendet wird, nicht auf das this einer umgebenden Methode zugreifen kann (Zeile A). Im Gegensatz dazu haben Pfeilfunktionen kein this als impliziten Parameter. Sie behandeln es wie jede andere Variable und können daher auf das this einer umgebenden Methode zugreifen (Zeile B)

const jill = {
  name: 'Jill',
  someMethod() {
    function ordinaryFunc() {
      assert.throws(
        () => this.name, // (A)
        /^TypeError: Cannot read properties of undefined \(reading 'name'\)$/);
    }
    ordinaryFunc();

    const arrowFunc = () => {
      assert.equal(this.name, 'Jill'); // (B)
    };
    arrowFunc();
  },
};
jill.someMethod();

In diesem Code können wir zwei Arten der Behandlung von this beobachten

25.3.4 Empfehlung: Bevorzugen Sie spezialisierte Funktionen gegenüber gewöhnlichen Funktionen

Normalerweise sollten Sie spezialisierte Funktionen gegenüber gewöhnlichen Funktionen bevorzugen, insbesondere Klassen und Methoden.

Wenn es um echte Funktionen geht, ist die Wahl zwischen einer Pfeilfunktion und einer gewöhnlichen Funktion weniger eindeutig

25.4 Zusammenfassung: Arten von aufrufbaren Werten

  Dieser Abschnitt bezieht sich auf zukünftige Inhalte

Dieser Abschnitt dient hauptsächlich als Referenz für die aktuellen und kommenden Kapitel. Machen Sie sich keine Sorgen, wenn Sie nicht alles verstehen.

Bisher waren alle (echten) Funktionen und Methoden, die wir gesehen haben

Spätere Kapitel werden andere Programmiermodi behandeln

Diese Modi können kombiniert werden – zum Beispiel gibt es synchrone Iterables und asynchrone Iterables.

Mehrere neue Arten von Funktionen und Methoden helfen bei einigen der Moduskombinationen

Das lässt uns mit 4 Arten (2 × 2) von Funktionen und Methoden

Tabelle 17 gibt einen Überblick über die Syntax zum Erstellen dieser 4 Arten von Funktionen und Methoden.

Tabelle 17: Syntax zum Erstellen von Funktionen und Methoden. Die letzte Spalte gibt an, wie viele Werte eine Entität produziert.
Ergebnis #
Synchrone Funktion Synchrone Methode
function f() {} { m() {} } Wert 1
f = function () {}
f = () => {}
Synchrone Generatorfunktion Synchrone Generator-Methode
function* f() {} { * m() {} } Iterable 0+
f = function* () {}
Async-Funktion Async-Methode
async function f() {} { async m() {} } Promise 1
f = async function () {}
f = async () => {}
Asynchrone Generatorfunktion Asynchrone Generator-Methode
async function* f() {} { async * m() {} } Async-Iterable 0+
f = async function* () {}

25.5 Rückgabe von Werten aus Funktionen und Methoden

(Alles, was in diesem Abschnitt erwähnt wird, gilt sowohl für Funktionen als auch für Methoden.)

Die return-Anweisung gibt explizit einen Wert aus einer Funktion zurück

function func() {
  return 123;
}
assert.equal(func(), 123);

Ein weiteres Beispiel

function boolToYesNo(bool) {
  if (bool) {
    return 'Yes';
  } else {
    return 'No';
  }
}
assert.equal(boolToYesNo(true), 'Yes');
assert.equal(boolToYesNo(false), 'No');

Wenn Sie am Ende einer Funktion nichts explizit zurückgegeben haben, gibt JavaScript für Sie undefined zurück

function noReturn() {
  // No explicit return
}
assert.equal(noReturn(), undefined);

25.6 Parameterbehandlung

Auch hier erwähne ich nur Funktionen in diesem Abschnitt, aber alles gilt auch für Methoden.

25.6.1 Terminologie: Parameter vs. Argumente

Der Begriff Parameter und der Begriff Argument bedeuten im Grunde dasselbe. Wenn Sie möchten, können Sie die folgende Unterscheidung treffen

25.6.2 Terminologie: Callback

Ein Callback oder Callback-Funktion ist eine Funktion, die ein Argument eines Funktions- oder Methodenaufrufs ist.

Das Folgende ist ein Beispiel für einen Callback

const myArray = ['a', 'b'];
const callback = (x) => console.log(x);
myArray.forEach(callback);

// Output:
// 'a'
// 'b'

25.6.3 Zu viele oder zu wenige Argumente

JavaScript beschwert sich nicht, wenn ein Funktionsaufruf eine andere Anzahl von Argumenten liefert als von der Funktionsdefinition erwartet

Zum Beispiel

function foo(x, y) {
  return [x, y];
}

// Too many arguments:
assert.deepEqual(foo('a', 'b', 'c'), ['a', 'b']);

// The expected number of arguments:
assert.deepEqual(foo('a', 'b'), ['a', 'b']);

// Not enough arguments:
assert.deepEqual(foo('a'), ['a', undefined]);

25.6.4 Standardwerte für Parameter

Parameter-Standardwerte legen den zu verwendenden Wert fest, wenn ein Parameter nicht bereitgestellt wurde – zum Beispiel

function f(x, y=0) {
  return [x, y];
}

assert.deepEqual(f(1), [1, 0]);
assert.deepEqual(f(), [undefined, 0]);

undefined löst ebenfalls den Standardwert aus

assert.deepEqual(
  f(undefined, undefined),
  [undefined, 0]);

25.6.5 Restparameter

Ein Restparameter wird deklariert, indem einem Bezeichner drei Punkte (...) vorangestellt werden. Während eines Funktions- oder Methodenaufrufs empfängt er ein Array mit allen verbleibenden Argumenten. Wenn am Ende keine zusätzlichen Argumente vorhanden sind, ist es ein leeres Array – zum Beispiel

function f(x, ...y) {
  return [x, y];
}
assert.deepEqual(
  f('a', 'b', 'c'), ['a', ['b', 'c']]
);
assert.deepEqual(
  f(), [undefined, []]
);

Es gibt zwei Einschränkungen hinsichtlich der Verwendung von Restparametern

25.6.5.1 Erzwingen einer bestimmten Anzahl von Argumenten über einen Restparameter

Sie können einen Restparameter verwenden, um eine bestimmte Anzahl von Argumenten zu erzwingen. Nehmen Sie zum Beispiel die folgende Funktion

function createPoint(x, y) {
  return {x, y};
    // same as {x: x, y: y}
}

So zwingen wir Aufrufer, immer zwei Argumente bereitzustellen

function createPoint(...args) {
  if (args.length !== 2) {
    throw new Error('Please provide exactly 2 arguments!');
  }
  const [x, y] = args; // (A)
  return {x, y};
}

In Zeile A greifen wir über Destrukturierung auf die Elemente von args zu.

25.6.6 Benannte Parameter

Wenn jemand eine Funktion aufruft, werden die vom Aufrufer bereitgestellten Argumente den vom Aufgerufenen empfangenen Parametern zugewiesen. Zwei gängige Möglichkeiten, die Zuordnung durchzuführen, sind

  1. Positionsbasierte Parameter: Ein Argument wird einem Parameter zugewiesen, wenn sie die gleiche Position haben. Ein Funktionsaufruf nur mit positionsbasierten Argumenten sieht wie folgt aus.

    selectEntries(3, 20, 2)
  2. Benannte Parameter: Ein Argument wird einem Parameter zugewiesen, wenn sie den gleichen Namen haben. JavaScript hat keine benannten Parameter, aber Sie können sie simulieren. Zum Beispiel ist dies ein Funktionsaufruf nur mit (simulierten) benannten Argumenten

    selectEntries({start: 3, end: 20, step: 2})

Benannte Parameter haben mehrere Vorteile

25.6.7 Simulation benannter Parameter

JavaScript hat keine echten benannten Parameter. Der offizielle Weg, sie zu simulieren, sind Objektliterale

function selectEntries({start=0, end=-1, step=1}) {
  return {start, end, step};
}

Diese Funktion verwendet Destrukturierung, um auf die Eigenschaften ihres einzelnen Parameters zuzugreifen. Das von ihr verwendete Muster ist eine Abkürzung für das folgende Muster

{start: start=0, end: end=-1, step: step=1}

Dieses Destrukturierungsmuster funktioniert für leere Objektliterale

> selectEntries({})
{ start: 0, end: -1, step: 1 }

Aber es funktioniert nicht, wenn Sie die Funktion ohne Argumente aufrufen

> selectEntries()
TypeError: Cannot read properties of undefined (reading 'start')

Sie können dies beheben, indem Sie einen Standardwert für das gesamte Muster bereitstellen. Dieser Standardwert funktioniert genauso wie Standardwerte für einfachere Parameterdefinitionen: Wenn der Parameter fehlt, wird der Standard verwendet.

function selectEntries({start=0, end=-1, step=1} = {}) {
  return {start, end, step};
}
assert.deepEqual(
  selectEntries(),
  { start: 0, end: -1, step: 1 });

25.6.8 Spread-Argumente (...) in Funktionsaufrufen

Wenn Sie drei Punkte (...) vor das Argument eines Funktionsaufrufs setzen, sprechen Sie es. Das bedeutet, dass das Argument ein Iterable-Objekt sein muss und die iterierten Werte alle zu Argumenten werden. Mit anderen Worten, ein einzelnes Argument wird in mehrere Argumente erweitert – zum Beispiel

function func(x, y) {
  console.log(x);
  console.log(y);
}
const someIterable = ['a', 'b'];
func(...someIterable);
  // same as func('a', 'b')

// Output:
// 'a'
// 'b'

Spread-Argumente und Restparameter verwenden die gleiche Syntax (...), dienen aber gegensätzlichen Zwecken

25.6.8.1 Beispiel: Spread in Math.max()

Math.max() gibt die größte seiner null oder mehr Argumente zurück. Leider kann es nicht für Arrays verwendet werden, aber Spread gibt uns einen Ausweg

> Math.max(-1, 5, 11, 3)
11
> Math.max(...[-1, 5, 11, 3])
11
> Math.max(-1, ...[-5, 11], 3)
11
25.6.8.2 Beispiel: Spread in Array.prototype.push()

Ähnlich fügt die Array-Methode .push() destruktiv ihre null oder mehr Parameter am Ende ihres Arrays hinzu. JavaScript hat keine Methode zum destruktiven Anhängen eines Arrays an ein anderes. Wieder einmal werden wir durch Spread gerettet

const arr1 = ['a', 'b'];
const arr2 = ['c', 'd'];

arr1.push(...arr2);
assert.deepEqual(arr1, ['a', 'b', 'c', 'd']);

  Übungen: Parameterbehandlung

25.7 Methoden von Funktionen: .call(), .apply(), .bind()

Funktionen sind Objekte und haben Methoden. In diesem Abschnitt befassen wir uns mit drei dieser Methoden: .call(), .apply() und .bind().

25.7.1 Die Funktionsmethode .call()

Jede Funktion someFunc hat die folgende Methode

someFunc.call(thisValue, arg1, arg2, arg3);

Dieser Methodenaufruf ist lose äquivalent zum folgenden Funktionsaufruf

someFunc(arg1, arg2, arg3);

Mit .call() können wir jedoch auch einen Wert für den impliziten Parameter this angeben. Mit anderen Worten: .call() macht den impliziten Parameter this explizit.

Der folgende Code demonstriert die Verwendung von .call()

function func(x, y) {
  return [this, x, y];
}

assert.deepEqual(
  func.call('hello', 'a', 'b'),
  ['hello', 'a', 'b']);

Wie wir bereits gesehen haben, ist bei einem Funktionsaufruf einer gewöhnlichen Funktion ihr this undefined

assert.deepEqual(
  func('a', 'b'),
  [undefined, 'a', 'b']);

Daher ist der vorherige Funktionsaufruf äquivalent zu

assert.deepEqual(
  func.call(undefined, 'a', 'b'),
  [undefined, 'a', 'b']);

In Pfeilfunktionen wird der Wert für this, der über .call() (oder andere Mittel) bereitgestellt wird, ignoriert.

25.7.2 Die Funktionsmethode .apply()

Jede Funktion someFunc hat die folgende Methode

someFunc.apply(thisValue, [arg1, arg2, arg3]);

Dieser Methodenaufruf ist lose äquivalent zum folgenden Funktionsaufruf (der Spreading verwendet)

someFunc(...[arg1, arg2, arg3]);

Mit .apply() können wir jedoch auch einen Wert für den impliziten Parameter this angeben.

Der folgende Code demonstriert die Verwendung von .apply()

function func(x, y) {
  return [this, x, y];
}

const args = ['a', 'b'];
assert.deepEqual(
  func.apply('hello', args),
  ['hello', 'a', 'b']);

25.7.3 Die Funktionsmethode .bind()

.bind() ist eine weitere Methode von Funktions-Objekten. Diese Methode wird wie folgt aufgerufen

const boundFunc = someFunc.bind(thisValue, arg1, arg2);

.bind() gibt eine neue Funktion boundFunc() zurück. Der Aufruf dieser Funktion ruft someFunc() mit this auf thisValue und diesen Parametern gesetzt auf: arg1, arg2, gefolgt von den Parametern von boundFunc().

Das heißt, die folgenden beiden Funktionsaufrufe sind äquivalent

boundFunc('a', 'b')
someFunc.call(thisValue, arg1, arg2, 'a', 'b')
25.7.3.1 Eine Alternative zu .bind()

Eine weitere Möglichkeit, this und Parameter vorab zu füllen, ist über eine Pfeilfunktion

const boundFunc2 = (...args) =>
  someFunc.call(thisValue, arg1, arg2, ...args);
25.7.3.2 Eine Implementierung von .bind()

Unter Berücksichtigung des vorherigen Abschnitts kann .bind() als echte Funktion wie folgt implementiert werden

function bind(func, thisValue, ...boundArgs) {
  return (...args) =>
    func.call(thisValue, ...boundArgs, ...args);
}
25.7.3.3 Beispiel: Binden einer echten Funktion

Die Verwendung von .bind() für echte Funktionen ist etwas unintuitiv, da wir einen Wert für this angeben müssen. Da dieser bei Funktionsaufrufen undefined ist, wird er normalerweise auf undefined oder null gesetzt.

Im folgenden Beispiel erstellen wir add8(), eine Funktion mit einem Parameter, indem wir den ersten Parameter von add() an 8 binden.

function add(x, y) {
  return x + y;
}

const add8 = add.bind(undefined, 8);
assert.equal(add8(1), 9);

  Quiz

Siehe Quiz-App.