Ich frage das aus Sicht des Sprachdesigns. Also versuche ich es herauszufinden
this
? this
ein Fehler oder konnte verbessert werden? Um zu verdeutlichen, warum ich mich bei this
nicht wohl fühle, beachte dieses Beispiel:
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?
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.
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%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%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.
Betrachten Sie das Idiom a.f()
als Abkürzung für:
Es ist definitionsgemäß ein Aufruf der Funktion f
mit dem Bereich a
.
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:
Tut mir leid, aber ich mag Python wirklich; -)
Tags und Links javascript language-design