Ich brauche:
var self = this;
viel in meinen Javascript 'Klassen'. Obwohl dies üblicherweise gemacht wird, fühlt es sich ein bisschen falsch an. Was ich in dieser Frage zu finden hoffe, ist ein besserer Weg, damit umzugehen, oder etwas, das mich davon überzeugt, dass dies in Ordnung ist.
Ist dies die Standardmethode, um die richtigen Bindungen beizubehalten? Sollte ich standardisieren, dass ich überall "Selbst" verwende, es sei denn, ich brauche ausdrücklich "Dies".
edit : Ich weiß genau, warum ich das brauche, ich frage mich nur, ob es ein bisschen böse ist und warum. Mir ist bekannt, dass es auch die integrierte Javascript-Funktion 'apply' gibt, mit der der Bereich beim Aufrufen einer Methode explizit definiert wird. Ist es besser?
javascript
Evert
quelle
quelle
var that = this
, ich habe mich ehrlich gesagt nicht einmal darum gekümmert, mich zu bewerben / anzurufen, aber jetzt habe ich über diese Methoden gelesen, danke für diese Frage!Antworten:
Wie andere gesagt haben: Diese "zusätzliche Variable" ist (auf einer bestimmten Ebene) der einzige Weg, um die Tatsache zu umgehen, dass
this
es sich um einen speziellen Ausdruck handelt und daher, da sie keine Variable ist, nicht an einen Ausführungskontext / -abschluss gebunden ist.Ich denke jedoch, dass Sie fragen (oder was ich wirklich beantworten möchte):
Zusammenfassung
Obwohl ich dies einmal versucht habe und dieselbe Frage hatte, verwende ich diesen Ansatz nicht mehr. Jetzt reserviere ich das Konstrukt für den Fall, dass ich Zugriff in einem Verschluss benötige. Für mich fügt es ein wenig hinzu "Hey, das ist was ich wirklich will!" semantisch zu meinem Code:
this -> this
undself -> this (but really that) in a closure
Fragen à la carte:
Tu, was sich für dich richtig anfühlt. Haben Sie keine Angst, eine Methode auszuprobieren und später zurückzuschalten (aber versuchen Sie bitte, in jedem Projekt konsistent zu bleiben :-)
"self" ist der am häufigsten verwendete Name. Wie oben, bevorzuge ich den umgekehrten Ansatz -
this
außer wenn eine Verschlussbindung erforderlich ist.Das Böse ist ein dummer subjektiver Begriff (wenn auch manchmal lustig). Ich habe nie gesagt, dass es böse ist, nur warum ich dem Ansatz nicht folge. Einige Leute sagen mir, ich sei "böse", weil ich keine Semikolons benutze. Ich sage ihnen, sie sollten sich eigentlich gute Argumente einfallen lassen und / oder JavaScript besser lernen :-)
Das Problem dabei
apply/call
ist, dass Sie sie am Punkt des Funktionsaufrufs verwenden müssen. Es hilft nicht, wenn jemand anderes eine Ihrer Methoden aufruft, da diethis
möglicherweise bereits deaktiviert ist. Dies ist am nützlichsten, wenn Sie beispielsweise Rückrufe im jQuery-Stil ausführen, bei denenthis
das Element / Element des Rückrufs usw. ist.Nebenbei...
Ich möchte vermeiden, dass Mitglieder sich selbst brauchen, und daher generell alle Mitgliederfunktionen auf Eigenschaften übertragen, bei denen der Empfänger (
this
) nur "durchfließt", was normalerweise "wie erwartet" ist.Die "privaten" Methoden in meinem Code beginnen mit einem "_" und wenn der Benutzer sie aufruft, ist das auf ihnen. Dies funktioniert auch besser (ist wirklich erforderlich), wenn der Prototyp-Ansatz für die Objekterstellung verwendet wird. Allerdings Douglas Crockford nicht einverstanden mit diesem „privaten“ Ansatz von mir und es gibt einige Fälle , in denen die Look-up - Kette Sie durch Injizieren eines unerwarteten Empfänger vereiteln kann:
Die Verwendung des im Konstruktor gebundenen "Selbst" sperrt auch die Obergrenze der Suchkette für eine Methode (sie ist nicht mehr nach oben polymorph!), Die möglicherweise korrekt ist oder nicht. Ich denke es ist normalerweise falsch.
Viel Spaß beim Codieren.
quelle
obj.member
normalerweise sicherstellt, dass die Methodethis
korrekt ist (seitobj->this(obj)->this(obj)->...
). Wenn Sie den Crockford-Link im Beitrag sehen, werden Sie sehen, dass der Ansatz der privaten Methode das Muster bricht, da die privaten "Methoden" jetzt in Variablen im Konstruktor gespeichert und somit nicht imobj.member
Formular aufgerufen werden. Dies wirdthis
in ihnen abgeworfen (wiethis
esobj
in den obigen Beispielen lediglich der Empfänger der Funktion zum Zeitpunkt des Aufrufs ist ), sofern keine zusätzliche Arbeit geleistet wird.aelf
ist das Fensterobjekt - ich würde es vermeiden, reservierte Wörter zu verwenden, undvar that = this
odervar _self = this
window.x
window.self
var self = false
den globalen Kontext ein und fügen Sie dortvar self = this;
Methoden hinzu, wo Sie sie benötigen. Dann, wenn Sie jemals Zweifel haben, schreiben Sie(self || this).method(...)
. Es ist eine schreckliche Codierung, aber es fühlt sich gut an.Ja, das ist der Standardweg.
Function.apply()
undFunction.call()
kann helfen, aber nicht immer.Folgendes berücksichtigen
function foo() { var self = this; this.name = 'foo'; setTimeout( function() { alert( "Hi from " + self.name ); }, 1000 ); } new foo();
Wenn Sie dies tun wollten, aber die Verwendung einer Variablen wie
self
und verwendencall()
oderapply()
stattdessen ... nun ... vermeiden möchten , schauen Sie sie sich an und beginnen zu versuchen, stellen jedoch bald fest, dass Sie dies einfach nicht können.setTimeout()
ist für den Aufruf des Lambda verantwortlich, sodass Sie diese alternativen Aufrufstile nicht nutzen können. Am Ende würden Sie immer noch eine Zwischenvariable erstellen, die einen Verweis auf das Objekt enthält.quelle
setTimeout( (function() { alert( "Hi from " + this.name ); }).apply(this), 1000 ); }
Es gibt keinen Standard für JavaScript und Klassen- / Instanzsysteme. Sie müssen auswählen, welche Art von Objektmodell Sie bevorzugen. Hier ist ein weiterer Link zu einem Hintergrund. Fazit: Es gibt keine Schlussfolgerung.
In der Regel geht das Speichern einer Kopie
var self= this;
(*) in einem Abschluss mit einem Objektmodell einher, das um Verschlüsse mit Kopien jeder Methode pro Instanz erstellt wird. Das ist eine gültige Art, Dinge zu tun. ein bisschen weniger effizient, aber auch in der Regel etwas weniger Arbeit als die Alternative, ein Objektmodell , Prototyping gebaut um, unter Verwendungthis
,apply()
und ECMAScript Fifth Editionbind()
gebundene Methoden zu erhalten.Was mehr als "böse" gezählt werden könnte, ist, wenn Sie einen Mischmasch beider Stile im selben Code haben. Leider tun dies viele gängige JS-Codes (weil wir ehrlich sind, versteht niemand das bizarre native Objektmodell von JavaScript wirklich ).
(*: Ich verwende normalerweise
that
anstelle vonself
; Sie können einen beliebigen Variablennamen verwenden, haben aberself
bereits eine etwas dunkle und völlig sinnlose Bedeutung alswindow
Mitglied, das auf das Fenster selbst zeigt.)quelle
Ich bin gerade auf diese Frage gestoßen, weil meine Mitarbeiter süchtig nach sich selbst / diesen Variablen waren und ich verstehen wollte, warum ...
Ich denke , dass es eine bessere Art und Weise ist, zu beschäftigen diese in nowdays:
function () {}.bind(this); // native _.bind(function () {}, this); // lodash $.proxy(function () {}, this); // jquery
quelle
In Javascript und anderen Sprachen mit Verschlüssen kann dies sehr wichtig sein. Das Objekt,
this
auf das in einer Methode verwiesen wird, kann sich tatsächlich ändern . Sobald Sie Ihreself
Variable gleich gesetzt habenthis
, bleibt self zuverlässig eine Referenz auf das betreffende Objekt, auch wennthis
später auf etwas anderes verwiesen wird .Dies ist ein wichtiger Unterschied zwischen Javascript und vielen anderen Sprachen, in denen wir arbeiten. Ich komme aus .Net, daher kam mir diese Art von Dingen zunächst auch seltsam vor.
Edit : Ah, okay, du weißt das alles. (Vielleicht immer noch hilfreich für jemand anderen.) Ich füge hinzu, dass Übernehmen (und Aufrufen) eher für die Verwendung von "von außen" geeignet sind und einer Funktion, die Sie aufrufen, einen bestimmten Bereich geben, den Sie bereits kennen. Sobald Sie sich in einer Funktion befinden und sich weiter unten in Verschlüssen befinden, wird die folgende Technik angewendet:
var self = this;
ist der geeignetere Weg ( einfach und klar ), um Ihren aktuellen Bereich zu verankern .
quelle
Dies geschieht höchstwahrscheinlich, um einen Verweis darauf zu erhalten,
this
wann sich der Geltungsbereich ändern wird (im Falle einer Schließung). Ich weiß nicht, dass ich es für eine schlechte Praxis oder ein schlechtes Muster an und für sich halten würde, nein. Sie sehen ähnliche Dinge häufig bei Bibliotheken wie jQuery und viel bei der Arbeit mit AJAX.quelle
Ich denke, es gibt ein Argument dafür, immer
var self = this
in jede Methode einbezogen zu werden : menschliche Faktoren.Es wird oft genug benötigt, damit Sie eine Mischung aus Methoden haben, auf die zugegriffen wird,
this
und andere, die sie verwendenself
für denselben Zweck verwenden. Wenn Sie Code von einem zum anderen verschieben, werden plötzlich eine Reihe von Fehlern angezeigt.Gleichzeitig ertappe ich mich dabei
self.foo
, aus Gewohnheit abwesend zu schreiben , wenn ich keine benötigt oder hinzugefügt habevar self = this
. Ich denke, es könnte Sinn machen, es sich zur Gewohnheit zu machen, es immer einzubeziehen, ob gebraucht oder nicht.Das einzige Problem ist ...
this
,self
oderthat
alle sind hässliche Pocken in Ihrem Code und ich hasse sie alle. Also ich denke , dass es besser ist , mit delegierten Methoden zu vermeiden , wo möglich , so dass Sie mit vermeiden könnenthis
,that
oderself
die überwiegende Mehrheit der Zeit, und die Verwendung ,.bind(this)
wenn Sie sonst greifen könnteself
/that
. Es ist sehr selten, dass Sie durch die Verwendung von Delegaten für den Prototyp ohnehin eine erhebliche Menge an Speicherplatz sparen.Ein netter Nebeneffekt dieses Ansatzes ist, dass Sie nicht allen privaten Variablen ein Präfix voranstellen müssen
_
, da diese wirklich privat sind und die öffentlichen Eigenschaften vom führendenthis.
Benutzer aufgerufen werden , wodurch Ihr Code besser lesbar wird.Wie Bobince sagte,
var that = this
ist besser, weil es nicht schattiertwindow.self
.self = this
klingt für mich weniger umständlich, aber manchmal erhalten Sie verwirrende Fehlermeldungen wieproperty myMethod not found on global
, weil Sie dieself = this
Zeile vergessen haben .quelle
Ich möchte nur darauf hinweisen, dass 'self' gleich 'window' ist. Versuchen Sie, window === self an die Konsole auszugeben. Sie sollten dieses Muster mit 'that' oder ähnlichem als Variablennamen verwenden. Vermeiden Sie die Verwendung von 'self', da es bereits vom Browser verwendet wird (ein Fehler, und Sie erstellen selbst eine globale Variable). Auch wenn es seltsam klingt, ist es besser, "das" für seinen Namen zu verwenden, da andere Entwickler sofort wissen, was Sie in Ihrem Code erreichen wollten. Vermeiden Sie die Verwendung nicht standardmäßiger Variablennamen. Ich glaube, dass dies ein wichtiger Hinweis ist, aber er wurde nur in einem Kommentar erwähnt, deshalb wollte ich ihn sichtbarer machen.
quelle
Es ist 6 Jahre später und ich muss einige Dinge hinzufügen:
bind()
ist jetzt häufig genug, um überall verwendet zu werden. Ich benutze es oft als Alternative. Manchmal fühlt es sich klarer an. Ich benutze immer noch gelegentlichvar self = this;
. obwohl.Pfeilfunktionen werden langsam nutzbar. Die Syntax ist etwas kürzer, was nett ist, aber ich denke, das Killer-Feature ist wirklich, dass sie standardmäßig immer an den übergeordneten Bereich gebunden sind.
Diese:
var self = this; var foo = function(a) { return self.b + a; };
Kann jetzt geschrieben werden als:
var foo = a => this.b + a;
Dies ist die "optimistischste" Verwendung von Pfeilfunktionen, aber sie ist ziemlich süß.
Und nur zum Schluss, es ist nichts falsch daran:
var self = this;
quelle
Ich mag das. Es ist "selbst" erklärend. Douglas Crockford hat dazu einige Dinge zu sagen. Er gibt an, dass die Verwendung von "das" Konvention ist. Sie können Crockford kostenlos sehen, wenn Sie zum Yui-Theater fahren und sich Videos über Javascript ansehen .
quelle