JavaScript-Funktionsbindung (dieses Schlüsselwort) ist nach der Zuweisung verloren

9

Dies ist eines der mysteriösesten Features in JavaScript. Nachdem Sie die Objektmethode einer anderen Variablen zugewiesen haben, ist die Bindung (dieses Schlüsselwort) verloren.

%Vor%

meine Frage ist:

1) Was passiert hinter der Aufgabe? var fx = john.greet;    Ist diese Kopie nach Wert oder Kopie als Referenz?    fx und john.greet zeigen auf zwei verschiedene Funktionen, richtig?

2) Da fx eine globale Methode ist, enthält die Scope-Kette nur ein globales Objekt. Was ist der Wert der Eigenschaft this im Variablenobjekt?

    
nandin 23.04.2010, 21:07
quelle

5 Antworten

6

1) fx und john.greet beziehen sich auf das gleiche Funktionsobjekt, die Zuweisungsoperation für Objekte, funktioniert durch Referenz .

Für primitive Werte wie String , Number , Boolean undefined oder null wird eine Kopie des Wertes erstellt.

2) Der Wert this bezieht sich auf das globale Objekt.

Der this -Wert ist keine Eigenschaft des Variablenobjekts und hat es nichts mit der scope chain zu tun, ist ein spezielles reserviertes Wort und wird implizit bestimmt, wenn ein Funktion wird aufgerufen (Sie können sie auch explizit über call oder apply setzen).

JavaScript verarbeitet intern eine Reference type , die aus zwei Komponenten besteht, der Stammobjekt und der Eigenschaftsname , wenn eine Funktion aufgerufen wird, wird der this Wert implizit durch Abrufen des Basisobjekts (durch das interne GetValue Betrieb).

Und schließlich ist der letzte Fall, in dem this implizit gesetzt ist, wenn Sie eine Funktion mit dem new -Operator, das Schlüsselwort this verweist auf ein neu erstelltes Objekt.

Kurz gesagt, hier ist, wie this implizit funktioniert :

1- Wenn eine Funktion als Methode aufgerufen wird (die Funktion wird als Mitglied eines Objekts aufgerufen):

%Vor%

2- A normaler Funktionsaufruf:

%Vor%

3- Wenn der Operator new verwendet wird:

%Vor%     
CMS 23.04.2010, 21:17
quelle
13

john.greet("Mark") ruft tatsächlich eine Funktion auf. Wenn Sie var fx = john.greet; ausführen, erhalten Sie einen Verweis auf die Funktion. Wenn Sie es aufrufen, ist this nicht an john gebunden. Was Sie tatsächlich tun ist window.fx("Mark") und so this ist das window Objekt. Sie waren auf dem richtigen Weg, als Sie sagten, dass es im globalen Kontext war. In dieser bestimmten Instanz ist das globale Objekt window , und daher ist fx tatsächlich window.fx .

Wenn Sie eine Funktionsreferenz haben, sollten Sie call oder apply , wenn Sie den Wert von this festlegen möchten. Versuchen Sie Folgendes:

%Vor%

Das erste Argument in call oder apply ist der Wert, der für this im Kontext des Funktionsaufrufs verwendet wird.

BEARBEITEN

Einige Leute erwähnten, dass das wirkliche Problem hier Verwirrung bezüglich eines Objektliterals gegenüber einer Instanz eines Objekts sein könnte. Sie erstellen ein Objektliteral, das sich auch wie ein Singleton verhält. Sie können keine neue Instanz dieses Objekts erstellen. In diesem Fall ist john eine Referenz auf dieses Objektliteral. In diesem Zusammenhang bezieht sich this in der Funktion greet auf das Objektliteral selbst. Wenn Sie also john.greet("Mark") aufrufen, ist this an john gebunden.

Wenn Sie einen Verweis auf john.greet nur von selbst erhalten und einer globalen Variablen zuweisen, tun Sie Folgendes:

%Vor%

In diesem Szenario ist this window , weil fx im Grunde window.fx ist (da das globale Objekt hier window ist. Angenommen, dieser Code wurde in eine andere -Funktion eingeschlossen , dann verweist das globale Objekt auf diese Funktion.

Wenn Sie mehrere Instanzen eines Objekts erstellen möchten, können Sie Folgendes tun:

%Vor%

Hier behält die Variable self (die für die Funktion lokal ist) einen Verweis auf die tatsächliche Instanz, da Sie sie beim Erstellen des Objekts an this binden.

Es gibt viele Best Practices für OOP in Javascript. Sie können Google und finden Sie heraus (es gibt viele Links). Ich empfehle besonders Sachen von Douglas Crockford zu lesen.

    
Vivin Paliath 23.04.2010 21:16
quelle
3

Wie ich es verstehe, weisen Sie diese Methode nur der Variablen "fx" zu. Der Kontext des John-Objekts ist nicht damit verbunden.

Oberhalb meines Kopfes bezieht sich "this" im Kontext von fx auf das globale Objekt, das im Kontext eines Browsers (glaube ich) äquivalent zu Ihrem Fensterobjekt ist.

(Bearbeitung zur Klärung des globalen Objekts. Sortierung)

    
Funkatron 23.04.2010 21:16
quelle
1

Da Sie fx nur auf die Greet-Methode und nicht auf das gesamte John-Objekt setzen, hat es kein Konzept für seine Eltern und wird global umschrieben. Im Grunde geht es wertmäßig dahin, dass nur die Methode kopiert wird.

Da die Funktion nun global ausgerichtet ist, wird "this" zum Window-Objekt.

Wenn Sie stattdessen fx auf John setzen, erhalten Sie, was erwartet wird.

%Vor%     
zachwood 23.04.2010 21:29
quelle
0

inspiriert von @Vivin Paliath Antwort, tatsächlich komme ich etwas neues heraus. Was mich betrifft, versuche ich immer mein Bestes, JavaScript-Programmierung genauso wie Java zu machen, besonders in OOP.

Also mein Vorschlag ist es zu vermeiden, dies so möglich wie möglich zu verwenden, wenn wir es zuerst tun

%Vor%

Wir sollten stattdessen in jeder Funktion (Prototypfunktion, was auch immer) selbst verwenden, aber wenn wir so etwas schreiben:

%Vor%

Dies wird nicht funktionieren, da prototype ein Objekt in MyObject ist. Es kann nicht auf private Mitglied self zugreifen, das zu MyObject gehört. Meine Lösung dafür ist einfach:

%Vor%

Dies bringt den Vorteil der Effizienz des Prototyps, und wir müssen uns auch nicht um all diese this Probleme kümmern. Obwohl wir viele MyObject.prototype.xxxx -Dinge eingeben werden.

Wenn dies Ihren Jungs hilfreich ist, geben Sie mir bitte Daumen hoch , damit ich Daumen hoch andere erreichen kann, danke.

    
zhouwubai 19.09.2013 17:27
quelle

Tags und Links