Der Verweis auf ECMA 5 muss präzisiert werden.
Ich gehe davon aus, dass dies ECMA-262 Edition 5 bedeutet. Es sollte beachtet werden, dass ECMA-262 (auch bekannt als ECMAScript oder weniger genau Javascript) eine allgemeine Skriptsprache ist, die in Internetbrowsern implementiert wurde. Ab dem Standard Edition 5.1:
Die folgenden Schritte werden ausgeführt, wenn die Steuerung in den Ausführungskontext für den im Funktionsobjekt F enthaltenen Funktionscode eintritt, ein Aufrufer dieses Argument bereitstellt und ein Aufrufer die Argumentliste bereitstellt:
- Wenn der Funktionscode ein strikter Code ist, setzen Sie ThisBinding auf thisArg.
- Andernfalls setzen Sie die ThisBinding auf das globale Objekt, wenn thisArg null oder undefiniert ist.
- Andernfalls, wenn Type (thisArg) kein Object ist, setzen Sie ThisBinding auf ToObject (thisArg).
- Andernfalls setzen Sie ThisBinding auf thisArg
- ... (nicht über "das")
Der Begriff "globales Objekt" bezieht sich auf jedes Objekt, das sich am Anfang der Bereichskette befindet. Für Browser wäre dies das "Fenster" -Objekt, dies ist jedoch eine Implementierungsoption (Windows Script Host hat ein unsichtbares globales Objekt, aber keinen strengen Modus, sodass unqualifizierte Referenzen auf seine Eigenschaften zugreifen und es kein globales "Selbst" gibt). Außerdem muss der "strikte Modus" explizit aktiviert werden, da er sonst nicht aktiv ist (Abschnitt 14.1 des Standards). Als solches würde ein undefiniertes "dies" immer noch in das globale Objekt (Fenster) in "ECMA 5" aufgelöst, wobei der strikte Modus nicht aktiv ist.
Die Antwort auf die Frage lautet also:
"this" bezieht sich immer auf das Objekt, das die Funktion aufruft. Wenn die Funktion nicht von einem Objekt aufgerufen wurde (dh kein Methodenaufruf), ist "this" (wie an die Funktion übergeben) "undefined". Wenn jedoch NICHT der strikte Modus verwendet wird, wird ein undefiniertes "dies" auf das globale Objekt gesetzt (Regel 2 oben).
"self" hat keine spezielle syntaktische Bedeutung, es ist nur eine Kennung. Browser neigen dazu, window.self (nur eine Eigenschaft des globalen Fensterobjekts) = window zu definieren. Dies führt dazu, dass uneingeschränkte Verweise auf "Selbst" dasselbe sind wie "Fenster", WENN "Selbst" in einem umschließenden Bereich neu definiert wurde (z. B. durch "var self = this;" oben. Viel Glück beim Neudefinieren von "this".)
Die vollständige Erklärung des obigen Beispiels lautet also:
outer func: this.foo = bar
// "this" refers to the invoking object "myObject"
outer func: self.foo = bar
// "self" resolves to the variable in the local scope which has been set to "this" so it is also "myObject"
inner func: this.foo = undefined
// "this" refers to the invoking object (none) and so is replaced by the global object (strict mode must be off). "window" has no foo property so its "value" is undefined.
inner func: self.foo = bar
// self resolves to the variable in the enclosing scope which is still "myObject"
Eine interessante Variation des Beispiels erzeugt einen Abschluss, indem ein Verweis auf die innere Funktion zurückgegeben wird.
var myObject = {
foo: "bar",
func: function() {
var self = this;
console.log("outer func: this.foo = " + this.foo);
console.log("outer func: self.foo = " + self.foo);
return function() {
console.log("inner func: this.foo = " + this.foo);
console.log("inner func: self.foo = " + self.foo);
};
}
};
var yourObject = {
foo: "blat",
func: myObject.func() // function call not function object
};
console.log("----");
yourObject.func();
Produzieren
outer func: this.foo = bar
outer func: self.foo = bar
----
inner func: this.foo = blat
inner func: self.foo = bar
Beachten Sie, dass die innere Funktion erst aufgerufen wird, wenn Sie von yourObject aufgerufen werden. Also ist this.foo jetzt yourObject.foo, aber self wird immer noch in die Variable im umschließenden Bereich aufgelöst, die zum Zeitpunkt der Rückgabe des inneren Funktionsobjekts myObject war (und in der resultierenden Schließung immer noch ist). Innerhalb der inneren Funktion bezieht sich "dies" auf das Objekt, das die innere Funktion aufruft, während sich "self" auf das Objekt bezieht, das die äußere Funktion aufgerufen hat, um den Verweis auf die innere Funktion zu erstellen.
Um die Zusammenfassung der Zusammenfassung zusammenzufassen, wird "dies" durch den Sprachstandard definiert, "selbst" wird durch denjenigen definiert, der sie definiert (Laufzeitimplementierer oder Endprogrammierer).