Was ist der Grund für das Verhalten des Schlüsselworts 'this' in JavaScript?

8

Ich frage das aus Sicht des Sprachdesigns. Also versuche ich es herauszufinden

  1. Was ist der Grund für das Verhalten von this ?
  2. In welchem ​​Maße war das Verhalten von this ein Fehler oder konnte verbessert werden?

Um zu verdeutlichen, warum ich mich bei this nicht wohl fühle, beachte dieses Beispiel:

%Vor%

Beachten Sie, wie leicht das Objekt, zu dem f() gehört, verloren geht: Getrennt von a wird this zum globalen Objekt ( window für Browser).

Betrachten Sie jetzt:

%Vor%

Ohne this zu verwenden, können wir den Objektkontext unabhängig davon, wo oder wie die Methode verwendet wird, einrichten und pflegen. Ich kann nicht anders, als zu denken, dass mit der Macht, die Schließungen bieten, this überflüssig wird und vielleicht sogar ein wenig gefährlich ...

Ich bin nicht gegen Vendetta gegen this oder suche nach einem Argument; Ich versuche nur, es besser zu verstehen. Ich weiß zu schätzen, dass "dies" nützlich sein kann, aber erkennen Sie, dass es verwirrend sein kann auch ... Sicherlich verwirrend für Anfänger und vielleicht auch für Experten in hinreichend obskuren Fällen.

Und dennoch bleibt es ein stark genutzter und anscheinend angesehener Teil der Sprache, in einer Zeit, in der andere Kernaspekte der Sprache als faires Spiel für das Meiden erscheinen (zB Crockford und with oder new ). . Was fehlt mir dann, das macht this unverzichtbar?

    
mike g 12.02.2009, 13:14
quelle

7 Antworten

11

Sie scheinen zu erwarten, dass sich dies in bestimmten OO-Sprachen verhält, wo es sich immer auf das Objekt bezieht, zu dem eine Methode gehört.

Aber in JavaScript kann eine Funktion an mehrere Objekte oder gar kein Objekt angehängt werden. In Ihrem Beispiel haben Sie eine Funktion geschrieben, die im Kontext von einem bestimmten Objekt verwendet werden soll. Aber nichts hindert mich daran, diese Funktion zu übernehmen und sie an ein anderes Objekt anzuhängen. Das ist nur die Natur der Sprache - Funktionen sind erstklassig, Objekt-Mitgliedschaft ist optional.

Daher bezieht sich this auf den Kontext, in dem eine Funktion aufgerufen wird. Dies ist entweder ein beliebiges Objekt (angegeben über . , .apply oder .call() ) oder das globale Objekt. In zukünftigen Versionen der Sprache wird auf den Kontext Bezug genommen, in dem die Funktion definiert wurde: das globale Objekt für globale Funktionen, das äußere this für innere Funktionen; Sie können dies als Korrektur eines Konstruktionsfehlers betrachten, da es in der Praxis möglich war, auf das globale Objekt zu verweisen, wobei dies nicht besonders nützlich war.

    
Shog9 12.02.2009, 16:11
quelle
8

Ich glaube nicht, dass das "ungebunden" ein Fehler war. Manchmal kann es anfangs verwirrend sein, aber es gibt gute Gründe dafür. Die erste, die mir in den Sinn kommt, ist, dass, da JavaScript keine klassenbasierte Sprache ist, Funktionen keiner bestimmten Klasse zugeordnet sind. Daher gibt es keine konsistente Möglichkeit, "dieses" automatisch an die korrekte Objektinstanz zu binden. Zum Beispiel

%Vor%

"this" muss sich auf ein Person-Objekt beziehen, aber die Funktion, die Person.prototype.getName zugewiesen ist, kann nicht wissen, wie es verwendet wird, also muss "this" an jedes Objekt gebunden sein es wird angerufen.

Wo dies ein Problem verursacht, ist, wenn Sie geschachtelte Funktionen haben.

%Vor%

Die Syntax artificialidiot vorgeschlagen würde bequem sein, aber es ist ziemlich einfach," das "an ein bestimmtes Objekt zu binden, indem Sie anwenden:

%Vor%

oder die "traditionellere" Methode, bei der Closures verwendet werden:

%Vor%     
Matthew Crumley 12.02.2009 15:50
quelle
3
  • Es war nicht
  • Viele OO-Sachen
  • Es ist gut so wie es ist
svinto 12.02.2009 13:21
quelle
3

Ich denke ungebunden "das" ist ein Fehler. Ansonsten ist es ziemlich praktisch. Unbound "this" eröffnet die Möglichkeit, den Kontext, der bei der Ereignisbehandlung von Browsern am deutlichsten sichtbar wird, falsch zu interpretieren. Auch JavaScript-Bibliotheken haben unterschiedliche Meinungen darüber, auf was sich "this" in der Ereignisbehandlung beziehen sollte und auf viele Callback-Konstrukte (wie map, filter).

Das Entfernen von ungebundenem "This" würde die Dinge wahrscheinlich nicht schwieriger machen.

Bearbeiten: Ich denke, ein alternatives Syntaxbeispiel wird meine Haltung klarer machen.

%Vor%     
artificialidiot 12.02.2009 13:47
quelle
1

Ich denke das ungebundene "this" -Schlüsselwort ist notwendig, weil JavaScript eine prototypbasierte Sprache ist. Jemand, der besser informiert ist, kann die Details hier eintragen.

Die Tatsache, dass es ist, ist jedoch nicht sehr hilfreich. Vor allem, wenn Sie die Methode eines Objekts an eine Funktion höherer Ordnung übergeben wollen, werden die Dinge hässlich (folgende Beispiele mit ein wenig Hilfe von MooTools):

%Vor%

Funktioniert nicht, da sich das 'this' in myObject.foo auf myArray anstelle von myObject bezieht. Stattdessen:

%Vor%

Was mir sehr hässlich erscheint. Deshalb programmiere ich in JavaScript normalerweise nicht objektorientiert, sondern verlasse mich eher auf Closures.

    
rix0rrr 12.02.2009 16:07
quelle
1

Betrachten Sie das Idiom a.f() als Abkürzung für:

%Vor%

Es ist definitionsgemäß ein Aufruf der Funktion f mit dem Bereich a .

%Vor%

Wenn this und a nicht dasselbe Objekt sind, verwenden f() und a.f() unterschiedliche Bereiche und können sich daher anders verhalten. Betrachten Sie die Unterscheidung zwischen statischen und Klassenmethoden in anderen Sprachen:

%Vor%     
Ates Goral 12.02.2009 16:08
quelle
1
  • Es sollte stattdessen "self" heißen
  • Alles, was sich auf aktuelle Objekte bezieht.
  • Indem Sie 'self' als Namen für 'this' wählen und es explizit (als erstes Argument) an alle Methoden übergeben. Auf diese Weise können Sie die Instanzmethode einfach von der statischen Methode oder von der Funktion unterscheiden.

Tut mir leid, aber ich mag Python wirklich; -)

    
Abgan 12.02.2009 13:35
quelle

Tags und Links