Odniesienie do ECMA 5 wymaga wyjaśnienia.
Zakładam, że oznacza to ECMA-262 wydanie 5. Należy zauważyć, że ECMA-262 (aka ECMAScript lub mniej dokładnie Javascript) jest ogólnym językiem skryptowym, który został zaimplementowany w przeglądarkach internetowych. Ze standardu Edition 5.1:
Poniższe kroki są wykonywane, gdy sterowanie wchodzi w kontekst wykonania dla kodu funkcji zawartego w obiekcie funkcji F, obiekt wywołujący podał thisArg i obiekt wywołujący podany argumentsList:
- Jeśli kod funkcji jest kodem ścisłym, ustaw ThisBinding na thisArg.
- W przeciwnym razie, jeśli thisArg ma wartość null lub undefined, ustaw ThisBinding na obiekt globalny.
- W przeciwnym razie, jeśli Type (thisArg) nie jest Object, ustaw ThisBinding na ToObject (thisArg).
- W przeciwnym razie ustaw ThisBinding na thisArg
- ... (nie o „tym”)
Termin „obiekt globalny” odnosi się do dowolnego obiektu znajdującego się na początku łańcucha zasięgu. W przypadku przeglądarek byłby to obiekt „window”, ale jest to wybór implementacji (Host skryptów systemu Windows ma niewidoczny obiekt globalny, ale nie ma trybu ścisłego, więc niekwalifikowane odwołania mają dostęp do jego właściwości i nie ma globalnego „własnego”). Ponadto „tryb ścisły” musi być jawnie włączony, w przeciwnym razie nie będzie aktywny (sekcja 14.1 normy). W związku z tym nieokreślone „this” nadal rozwiązywałoby się do obiektu globalnego (okna) w „ECMA 5” z nieaktywnym trybem ścisłym.
Tak więc odpowiedź na pytanie brzmi:
„this” zawsze odnosi się do obiektu wywołującego funkcję. Jeśli funkcja nie została wywołana przez obiekt (tj. Nie została wywołana metoda), wówczas „this” (przekazane do funkcji) jest „niezdefiniowane”. Jednakże, jeśli NIE używasz trybu ścisłego, to niezdefiniowane „this” jest ustawiane na obiekt globalny (zasada 2 powyżej).
„Ja” nie ma specjalnego znaczenia składniowego, jest tylko identyfikatorem. Przeglądarki mają tendencję do definiowania window.self (tylko właściwość globalnego obiektu window) = window. Powoduje to, że niekwalifikowane odniesienia do „self” są tym samym, co „okno”, chyba że „self” zostało przedefiniowane w ramach obejmującego zakresu (na przykład przez „var self = this;” powyżej. Powodzenia w ponownym definiowaniu „this”).
Zatem pełne wyjaśnienie powyższego przykładu jest następujące:
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"
Ciekawa odmiana przykładu tworzy zamknięcie, zwracając odwołanie do funkcji wewnętrznej.
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();
Produkujemy
outer func: this.foo = bar
outer func: self.foo = bar
----
inner func: this.foo = blat
inner func: self.foo = bar
Zwróć uwagę, że funkcja wewnętrzna nie jest wywoływana, dopóki nie zostanie wywołana przez yourObject. Więc this.foo to teraz yourObject.foo, ale self nadal jest rozpoznawane jako zmienna w otaczającym zakresie, która w momencie zwrócenia wewnętrznego obiektu funkcji była (iw wynikowym zamknięciu nadal jest) myObject. Zatem w ramach funkcji wewnętrznej „this” odnosi się do obiektu wywołującego funkcję wewnętrzną, podczas gdy „self” odnosi się do obiektu, który wywołał funkcję zewnętrzną, aby utworzyć odniesienie do funkcji wewnętrznej.
Podsumowując podsumowanie podsumowania, „this” jest zdefiniowane przez standard języka, „self” jest definiowane przez tego, kto je definiuje (realizator wykonawczy lub programista końcowy).