Il riferimento all'ECMA 5 deve essere chiarito.
Presumo che significhi ECMA-262 Edizione 5. Va notato che ECMA-262 (noto anche come ECMAScript o, meno precisamente, Javascript) è un linguaggio di scripting generale che è stato implementato nei browser Internet. Dallo standard Edition 5.1:
I seguenti passaggi vengono eseguiti quando il controllo entra nel contesto di esecuzione per il codice funzione contenuto nell'oggetto funzione F, un chiamante ha fornito thisArg e un chiamante ha fornito argumentsList:
- Se il codice della funzione è un codice rigoroso, impostare ThisBinding su thisArg.
- Altrimenti, se thisArg è null o undefined, impostare ThisBinding sull'oggetto globale.
- Altrimenti, se Type (thisArg) non è Object, impostare ThisBinding su ToObject (thisArg).
- Altrimenti imposta ThisBinding su thisArg
- ... (non su "questo")
Il termine "oggetto globale" si riferisce a qualsiasi oggetto si trovi all'inizio della catena dell'ambito. Per i browser questo sarebbe l'oggetto "finestra" ma questa è una scelta di implementazione (Windows Script Host ha un oggetto globale invisibile ma nessuna modalità rigorosa, quindi i riferimenti non qualificati accedono alle sue proprietà e non esiste un "sé" globale). Inoltre, la "modalità rigorosa" deve essere abilitata esplicitamente altrimenti non è attiva (sezione 14.1 dello standard). In quanto tale, un "this" non definito sarebbe comunque risolto nell'oggetto globale (finestra) in "ECMA 5" con la modalità rigorosa non attiva.
Quindi la risposta alla domanda è:
"questo" si riferisce sempre all'oggetto che richiama la funzione. Se la funzione non è stata invocata da un oggetto (cioè non una chiamata a un metodo), "this" (come passato alla funzione) è "undefined". Tuttavia, se NON si utilizza la modalità rigorosa, un "questo" non definito viene impostato sull'oggetto globale (regola 2 sopra).
"sé" non ha un significato sintattico speciale, è solo un identificatore. I browser tendono a definire window.self (solo una proprietà dell'oggetto finestra globale) = window. Ciò si traduce in riferimenti non qualificati a "self" che sono uguali a "finestra" A MENO CHE "self" non sia stato ridefinito all'interno di un ambito di chiusura (come da "var self = this;" sopra. Buona fortuna ridefinendo "this".)
Quindi la spiegazione completa dell'esempio sopra è:
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"
Una variazione interessante dell'esempio crea una chiusura restituendo un riferimento alla funzione interna.
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();
Produrre
outer func: this.foo = bar
outer func: self.foo = bar
----
inner func: this.foo = blat
inner func: self.foo = bar
Nota come la funzione interna non viene chiamata fino a quando non viene invocata da yourObject. Quindi this.foo è ora yourObject.foo ma self si risolve ancora nella variabile nello scope di inclusione che, nel momento in cui è stato restituito l'oggetto funzione interna, era (e nella chiusura risultante è ancora) myObject. Quindi, all'interno della funzione interna, "questo" si riferisce all'oggetto che chiama la funzione interna mentre "sé" si riferisce all'oggetto che ha chiamato la funzione esterna per creare il riferimento alla funzione interna.
Per riassumere il sommario del sommario, "questo" è definito dallo standard del linguaggio, "self" è definito da chi lo definisce (implementatore runtime o programmatore finale).