Die vollständige Anleitung dazu in JavaScript

In JavaScript wird für jede Funktion thisautomatisch eine Referenz erstellt, wenn Sie sie deklarieren.

JavaScript thisist einer thisReferenz in anderen klassenbasierten Sprachen wie Java oder C # ziemlich ähnlich (JavaScript ist eine prototypbasierte Sprache und kein "Klassen" -Konzept): Es zeigt auf das Objekt, das die Funktion aufruft (dieses Objekt wird manchmal aufgerufen) als Kontext ). In JavaScript kann die thisReferenz innerhalb von Funktionen jedoch an verschiedene Objekte gebunden werden, je nachdem, wo die Funktion aufgerufen wird .

Hier sind 5 Grundregeln für das thisBinden in JavaScript:

Regel 1

Wenn eine Funktion im globalen Bereich aufgerufen wird, ist die thisReferenz standardmäßig an das globale Objekt gebunden ( windowim Browser oder globalin Node.js). Zum Beispiel:

function foo() { this.a = 2; } foo(); console.log(a); // 2

Hinweis: Wenn Sie die foo()obige Funktion im strengen Modus deklarieren , rufen Sie diese Funktion im globalen Bereich thisauf undefinedund die Zuweisung this.a = 2löst eine Uncaught TypeErrorAusnahme aus.

Regel 2

Lassen Sie uns das folgende Beispiel untersuchen:

function foo() { this.a = 2; } const obj = { foo: foo }; obj.foo(); console.log(obj.a); // 2

Im obigen Snippet wird die foo()Funktion mit dem Kontext is objobject aufgerufen , an den thisjetzt die Referenz gebunden ist obj. Wenn also eine Funktion mit einem Kontextobjekt aufgerufen wird, wird die thisReferenz an dieses Objekt gebunden.

Regel 3

.call, .applyUnd .bindkönnen alle an der Aufrufstelle explizit binden verwendet werden this. Die Verwendung .bind(this)ist etwas, das Sie in vielen React-Komponenten sehen können.

const foo = function() { console.log(this.bar) } foo.call({ bar: 1 }) // 1

Hier ist ein kurzes Beispiel, wie jeder zum Binden verwendet wird this:

  • .call():: fn.call(thisObj, fnParam1, fnParam2)
  • .apply():: fn.apply(thisObj, [fnParam1, fnParam2])
  • .bind():: const newFn = fn.bind(thisObj, fnParam1, fnParam2)

Regel 4

function Point2D(x, y) { this.x = x; this.y = y; } const p1 = new Point2D(1, 2); console.log(p1.x); // 1 console.log(p1.y); // 2

Das, was Sie beachten müssen, ist die Point2DFunktion, die mit dem newSchlüsselwort aufgerufen wird , und die thisReferenz ist an das p1Objekt gebunden . Wenn eine Funktion mit einem newSchlüsselwort aufgerufen wird, wird ein neues Objekt erstellt und die thisReferenz an dieses Objekt gebunden.

Hinweis: Wenn Sie eine Funktion mit einem newSchlüsselwort aufrufen, wird sie auch als Konstruktorfunktion aufgerufen .

Regel 5

JavaScript bestimmt den Wert von thiszur Laufzeit basierend auf dem aktuellen Kontext. So thiskann manchmal etwas zeigen andere als das, was Sie erwarten.

Betrachten Sie dieses Beispiel einer Cat-Klasse mit einer Methode makeSound(), die nach dem Muster in Regel 4 (oben) mit einer Konstruktorfunktion und dem newSchlüsselwort aufgerufen wird .

const Cat = function(name, sound) { this.name = name; this.sound = sound; this.makeSound = function() { console.log( this.name + ' says: ' + this.sound ); }; } const kitty = new Cat('Fat Daddy', 'Mrrooowww'); kitty.makeSound(); // Fat Daddy says: Mrrooowww

Versuchen wir nun, der Katze einen Weg zu den annoy()Menschen zu geben, indem wir ihren Ton 100 Mal wiederholen, einmal alle halbe Sekunde.

const Cat = function(name, sound) { this.name = name; this.sound = sound; this.makeSound = function() { console.log( this.name + ' says: ' + this.sound ); }; this.annoy = function() { let count = 0, max = 100; const t = setInterval(function() { this.makeSound(); // <-- this line fails with `this.makeSound is not a function` count++; if (count === max) { clearTimeout(t); } }, 500); }; } const kitty = new Cat('Fat Daddy', 'Mrrooowww'); kitty.annoy();

Das funktioniert nicht, weil setIntervalwir innerhalb des Rückrufs einen neuen Kontext mit globalem Gültigkeitsbereich erstellt haben und daher thisnicht mehr auf unsere Kitty-Instanz verweisen. Zeigt in einem Webbrowser thisstattdessen auf das Window-Objekt, das keine makeSound()Methode hat.

Ein paar Möglichkeiten, damit es funktioniert:

  1. Weisen Sie vor dem Erstellen des neuen Kontexts thiseine lokale Variable mit dem Namen meoder selfoder wie auch immer Sie sie aufrufen möchten zu und verwenden Sie diese Variable im Rückruf.
const Cat = function(name, sound) { this.name = name; this.sound = sound; this.makeSound = function() { console.log( this.name + ' says: ' + this.sound ); }; this.annoy = function() { let count = 0, max = 100; const self = this; const t = setInterval(function() { self.makeSound(); count++; if (count === max) { clearTimeout(t); } }, 500); }; } const kitty = new Cat('Fat Daddy', 'Mrrooowww'); kitty.annoy();
  1. Mit ES6 können Sie die Zuweisung thiszu einer lokalen Variablen vermeiden, indem Sie eine Pfeilfunktion verwenden, die an thisden Kontext des umgebenden Codes gebunden ist, in dem er definiert ist.
const Cat = function(name, sound) { this.name = name; this.sound = sound; this.makeSound = function() { console.log( this.name + ' says: ' + this.sound ); }; this.annoy = function() { let count = 0, max = 100; const t = setInterval(() => { this.makeSound(); count++; if (count === max) { clearTimeout(t); } }, 500); }; } const kitty = new Cat('Fat Daddy', 'Mrrooowww'); kitty.annoy();