call und apply in JavaScript: Top-Fehler und wie man sie vermeidet
Haben Sie jemals fremden JavaScript-Code angesehen und seltsame Konstrukte wie func.call(this, arg1, arg2) oder func.apply(this, [arg1, arg2]) gesehen? Und sich gefragt: "Wo liegt eigentlich der Unterschied?" Wenn ja – sind Sie nicht allein. Die Frage "What is the difference between call and apply?" ist eine der beliebtesten auf Stack Overflow mit hunderttausenden Aufrufen. Und das ist kein Zufall.
Die Verwechslung zwischen call und apply ist eine klassische Falle für Anfänger (und nicht nur für sie). In diesem Artikel erklären wir nicht nur die Theorie. Wir analysieren die Top-5 echten Fehler, zeigen, wie man sie behebt, und geben einen klaren Algorithmus, der Sie für immer von der Verwirrung befreit. Los geht's!
Kurze Einführung: Was sind call und apply?
Bevor wir in die Fehler eintauchen, frischen wir die Grundlagen auf. Die Methoden call und apply sind eingebaute Methoden von Funktionen in JavaScript. Ihre Hauptaufgabe ist es, den Kontext (this) für eine Funktion explizit anzugeben. Mit anderen Worten, sie erlauben es zu sagen: "Hey Funktion, stell dir vor, du arbeitest mit diesem Objekt".
Syntax:
func.call(context, arg1, arg2, ...);func.apply(context, [arg1, arg2, ...]);Der entscheidende Unterschied:
callakzeptiert Argumente durch Komma getrennt (als Liste).applyakzeptiert Argumente als Array (oder array-ähnliches Objekt).
Das ist alles. Das ist der einzige Unterschied. Aber genau wegen dieser "Kleinigkeit" entstehen die meisten Fehler. Lassen Sie uns diese analysieren.
Top-5 Fehler bei der Arbeit mit call und apply
Fehler Nr. 1: Verwechslung der Argumentliste (der häufigste!)
Dies ist der "König" aller Fehler. Sie haben eine Funktion geschrieben, die Argumente einzeln erwartet, aber Sie übergeben ein Array mit call. Oder umgekehrt.
Katastrophen-Beispiel:
function greet(greeting, punctuation) { console.log(greeting + ', ' + this.name + punctuation);}
const user = { name: 'Anna' };
// Fehler: Wir übergeben ein Array, verwenden aber callgreet.call(user, ['Hallo', '!']); // Ausgabe: "Hallo,! Anna,undefined" — völliger Unsinn!Warum ist das so? call erwartet Argumente einzeln. Es hat ein Argument erhalten – ein ganzes Array – und dieses in die Variable greeting gelegt. punctuation blieb undefined.
Wie behebt man das? Verwenden Sie apply, wenn die Daten bereits in einem Array vorliegen:
greet.apply(user, ['Hallo', '!']); // Ausgabe: "Hallo, Anna!" — richtig!Oder entpacken Sie das Array mit dem Spread-Operator (moderner Ansatz):
greet.call(user, ...['Hallo', '!']); // Funktioniert auch!Fehler Nr. 2: Vergessen, dass apply mit array-ähnlichen Objekten funktioniert
Viele denken, dass apply nur echte Arrays akzeptiert. Tatsächlich akzeptiert es jedes array-ähnliche Objekt (array-like object): Es muss eine length-Eigenschaft und numerische Schlüssel haben.
Beispiel:
function sum() { let total = 0; for (let i = 0; i < arguments.length; i++) { total += arguments[i]; } return total;}
// Wir übergeben kein Array, sondern ein Objekt mit lengthconst args = { 0: 5, 1: 10, 2: 15, length: 3 };
console.log(sum.apply(null, args)); // Ausgabe: 30 — funktioniert!Aber seien Sie vorsichtig: Wenn das Objekt keine length-Eigenschaft hat, ignoriert apply es einfach. Dies ist ein häufiger Fehler bei der Arbeit mit arguments (veraltetes Objekt) oder mit NodeList.
Fehler Nr. 3: Verwendung von call/apply, wo ein einfacher Aufruf ausreicht
Manchmal missbrauchen Anfänger die