Ich habe eine Frage dazu, wie der Zeiger "this" in einem verschachtelten Funktionsszenario behandelt wird.
Angenommen, ich füge den folgenden Beispielcode in eine Webseite ein. Ich erhalte eine Fehlermeldung, wenn ich die verschachtelte Funktion "doSomeEffects ()" aufrufe. Ich habe Firebug eingecheckt und es zeigt an, dass der Zeiger "this" in dieser verschachtelten Funktion tatsächlich auf das globale "window" -Objekt zeigt - was ich nicht erwartet hatte. Ich muss etwas nicht richtig verstehen, weil ich dachte, da ich die verschachtelte Funktion innerhalb einer Funktion des Objekts deklariert habe, sollte sie in Bezug auf die Funktion einen "lokalen" Bereich haben (dh der "this" -Zeiger würde sich wie auf das Objekt selbst beziehen wie es in meiner ersten "wenn" -Anweisung ist).
Alle Hinweise (kein Wortspiel beabsichtigt) wäre dankbar.
var std_obj = {
options : { rows: 0, cols: 0 },
activeEffect : "none",
displayMe : function() {
// the 'this' pointer is referring to the std_obj
if (this.activeEffect=="fade") { }
var doSomeEffects = function() {
// the 'this' pointer is referring to the window obj, why?
if (this.activeEffect=="fade") { }
}
doSomeEffects();
}
};
std_obj.displayMe();
quelle
this
Bezieht sich bei Verwendung innerhalb einer Funktion auf das Objekt, für das die Funktion aufgerufen wird.var self = this;
und dannself
in der inneren Funktion durch Schließen darauf verweisen .doSomeEffects
ist nicht mit einem bestimmten Objekt verbunden, daherthis
wird angenommen, dass es das Fenster ist, die Mutter aller Elemente.Antworten:
In JavaScript
this
basiert das Objekt wirklich darauf, wie Sie Ihre Funktionsaufrufe ausführen.Im Allgemeinen gibt es drei Möglichkeiten, das
this
Objekt einzurichten :someThing.someFunction(arg1, arg2, argN)
someFunction.call(someThing, arg1, arg2, argN)
someFunction.apply(someThing, [arg1, arg2, argN])
In allen obigen Beispielen wird das
this
Objekt seinsomeThing
. Wenn Sie eine Funktion ohne ein führendes übergeordnetes Objekt aufrufen, erhalten Sie im Allgemeinen das globale Objekt, das in den meisten Browsern daswindow
Objekt bedeutet .quelle
this.doSomeEffects();
basierend auf Ihrer Antwort geändert , aber es funktioniert immer noch nicht. Warum?this
inthis.doSomeEffects()
Punkten zustd_obj
. Wie in der obigen Antwort erläutert, muss eine Funktion, die keine Objektreferenz hatthis
, ein Fensterobjekt sein.Da dies zu den am häufigsten gestellten Fragen dieser Art zu gehören scheint, möchte ich nach all den Jahren die ES6-Lösung mit Pfeilfunktionen hinzufügen:
quelle
this
ist nicht Teil des Schließungsbereichs, sondern kann als zusätzlicher Parameter für die Funktion angesehen werden, die an der Aufrufstelle gebunden ist. Wenn die Methode nicht als Methode aufgerufen wird, wird das globale Objekt als übergebenthis
. Im Browser ist das globale Objekt identisch mitwindow
. Betrachten Sie zum Beispiel die folgende Funktion:und das folgende Objekt,
Wenn Sie die Funktion mit Methodensyntax aufrufen, z.
dann
this
ist gebunden anobj
.Wenn Sie someFunction () direkt aufrufen, z.
dann
this
ist an das globale Objekt gebunden, das heißtwindow
.Die häufigste Lösung besteht darin, dies in den Verschluss zu erfassen, z.
quelle
Es gibt einen Unterschied zwischen Gehäusevariablen und "dies". "this" wird tatsächlich vom Aufrufer der Funktion definiert, während explizite Variablen innerhalb des als Enclosure bezeichneten Funktionsdeklarationsblocks intakt bleiben. Siehe das folgende Beispiel:
Sie können es hier ausprobieren: http://jsfiddle.net/kSTBy/
Was in Ihrer Funktion passiert, ist "doSomeEffects ()", wird explizit aufgerufen, dies bedeutet Kontext oder das "Dies" der Funktion ist das Fenster. Wenn "doSomeEffects" eine Prototypmethode wäre, z. B. this.doSomeEffects bei "myObject", würde myObject.doSomeEffects () dazu führen, dass "this" "myObject" ist.
quelle
_this.name = myFirstObject this.name = mySecondObject
Um diese Frage zu verstehen, versuchen Sie, die Ausgabe für das folgende Snippet abzurufen
Der obige Code gibt Folgendes an die Konsole aus:
In der äußeren Funktion beziehen sich sowohl dies als auch selbst auf myObject und können daher beide richtig auf foo verweisen und darauf zugreifen.
In der inneren Funktion bezieht sich dies jedoch nicht mehr auf myObject. Infolgedessen ist this.foo in der inneren Funktion undefiniert, während der Verweis auf die lokale Variable self im Gültigkeitsbereich bleibt und dort zugänglich ist. (Vor ECMA 5 würde sich dies in der inneren Funktion auf das globale Fensterobjekt beziehen; während dies in ECMA 5 in der inneren Funktion undefiniert wäre.)
quelle
this
bezieht sich auf das Fensterobjekt (in einer Browser-Umgebung) oder GLOBAL-Objekt (in einer node.js-Umgebung)this
bezieht sich nicht mehr auf windowWie von Kyle erklärt, können Sie innerhalb der Funktion Folgendes verwenden
call
oderapply
angebenthis
:Hier ist das Konzept, das auf Ihren Code angewendet wird:
JsFiddle
quelle
Ich habe auch die Warnung " Möglicherweise ungültiger Referenzzugriff auf ein Klassenfeld über dieses " erhalten.
quelle
Da es nicht erwähnt wurde, werde ich erwähnen, dass die Verwendung
.bind()
eine Lösung ist -Hier ist ein einfacheres Beispiel -
Es ist wahr, dass die Verwendung einer
=>
Pfeilfunktion schlanker aussieht und für den Programmierer einfach ist. Es sollte jedoch berücksichtigt werden, dass ein lexikalischer Bereich wahrscheinlich mehr Arbeit in Bezug auf Verarbeitung und Speicher erfordert, um diesen lexikalischen Bereich einzurichten und beizubehalten, als einfach eine Funktionthis
mit einem Zeiger über zu verknüpfen.bind()
.Ein Teil des Vorteils der Entwicklung von Klassen in JS bestand darin, eine Methode bereitzustellen, um
this
zuverlässiger präsent und verfügbar zu sein, sich von funktionaler Programmierung und lexikalischen Bereichen abzuwenden und so den Overhead zu reduzieren.Von MDN
quelle