JavaScript posiada inną koncepcję odnośnie tego na co wskazuje słowo kluczowe
this, niż większość innych języków programowania. Istnieje dokładnie
pięć różnych sytuacji, w których wartość this jest przypisana w języku JavaScript.
this;
Używanie this w globalnym zasięgu, zwróci po prostu referencję do obiektu global.
foo();
Tutaj this również będzie wskazywało na obiekt global
Uwaga ES5: W trybie strict mode, przypadki z globalnym zasięgiem nie mają miejsca. W tym przypadku
thiszwróciundefinedzamiast wartości.
test.foo();
W tym przypadku this będzie wskazywało na test.
new foo();
Wywołanie funkcji, które jest poprzedzone słowem kluczowym new, zachowuje się
jak konstruktor. Wewnątrz funkcji this będzie
wskazywało na nowo utworzony obiekt.
function foo(a, b, c) {}
var bar = {};
foo.apply(bar, [1, 2, 3]); // tablica zostanie zamieniona w to co poniżej
foo.call(bar, 1, 2, 3); // rezultat a = 1, b = 2, c = 3
Używając metod call lub apply z prototypu Function.prototype, wartość this
wewnątrz wołanej funkcji zostanie jawnie ustawiona na pierwszy argument przekazany
podczas wywołania tych metod.
Zatem w powyższym przykładzie przypadek Wywoływanie metody nie będzie miał
miejsca i this wewnątrz foo będzie wskazywać na bar.
Uwaga:
thisnie może zostać użyte jako referencja do obiektu wewnątrz literałuObject. Zatemvar obj = {me: this}nie spowoduje, żemebędzie wskazywać naobj,thiszostaje związane z wartością tylko w powyższych pięciu wylistowanych przypadkach.
Mimo iż Większość z tych przypadków ma sens, to pierwszy przypadek powinien być traktowany jako błąd podczas projektowania języka i nigdy nie wykorzystywany w praktyce.
Foo.method = function() {
function test() {
// wewnątrz tej funkcji this wskazuje na obiekt global
}
test();
}
Powszechnym błędem jest myślenie, że this wewnątrz test wskazuje na Foo,
podczas gdy w rzeczywistości tak nie jest.
Aby uzyskać dostęp do Foo wewnątrz test, niezbędne jest stworzenie wewnątrz
metody lokalnej zmiennej, która będzie wskazywała na Foo.
Foo.method = function() {
var that = this;
function test() {
// Należy używać that zamiast this wewnątrz tej funkcji
}
test();
}
that jest zwykłą zmienną, ale jest to powszechnie stosowana konwencja otrzymywania
wartości zewnętrznego this. W połączeniu z domknięciami(closures),
jest to sposób na przekazywanie wartości this wokół.
Kolejną rzeczą, która nie działa w języku JavaScript, jest nadawanie aliasów funkcjom, co oznacza przypisanie metody do zmiennej.
var test = someObject.methodTest;
test();
Podobnie jak w pierwszym przypadku test zachowuje się jak wywołanie zwykłej
funkcji, a zatem wewnątrz funkcji this już nie będzie wskazywało someObject.
Podczas gdy późne wiązanie this może się na początku wydawać złym pomysłem,
to w rzeczywistości jest to rzecz, która sprawia, że
dziedziczenie prototypowe działa.
function Foo() {}
Foo.prototype.method = function() {};
function Bar() {}
Bar.prototype = Foo.prototype;
new Bar().method();
Kiedy metoda method zostanie wywołana na instancji Bar, this będzie
wskazywało właśnie tę instancję.