Używanie „this” w Javie i JavaScript. Czyli niby to samo, ale jednak coś innego. { weekly#1 }

Prowadzenie bloga to jednak nie taka prosta rzecz. Przy nadmiarze obowiązków, pracy i ciągłej nauce znalezienie czasu na pisanie kolejnych notek nie jest takie łatwe. Bo przecież trzeba jeszcze korzystać z życia. Postanowiłem więc publikować raczej krótkie wpisy, skupione na konkretnych problemach. Takich, z którymi sam się mierze w swojej pracy czy nauce. I mam nadzieję, że uda mi się takie notki publikować co tydzień.

Na początku poruszę temat z pogranicza dwóch języków. Java JavaScript nie mają ze sobą wiele wspólnego, a chyba najbardziej łączy je sama nazwa. Jest jednak coś co mi, jako typowemu javowcowi, na początku wydawało się w JS podobne, ale z czasem zacząłem dostrzegać sporo różnic. Chodzi o użycie słówka this obu językach.

Zacznijmy od krótkiego przypomnienia definicji słówka this w obu językach. W Javie wg dokumentacji Oracle jest to:

Within an instance method or a constructor, this is a reference to the current object — the object whose method or constructor is being called. You can refer to any member of the current object from within an instance method or a constructor by using this.

https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html

Czyli innymi słowy, this służy odwołaniu się do zmiennych, metod, konstruktorów (itd.) zdefiniowanych na poziomie klasy. Czyli za pomocą this możemy odwołać się do zmiennych obiektowych (danej instancji), a nie do zmiennych zdefiniowanych np. jako parametry danej metody czy konstruktora. Za pomocą this możemy również wywołać sam konstruktor.

class Example{

   String name;

   public Example(String name) {
      this.name = name;
   }

   public Example() {
      this(null); // użycie konstruktora Example(String name)
   }
}

W Javie nie ma konieczności stosowania słówka this. Jeżeli w powyższym przykładzie zadeklarujemy parametr pod inną nazwą niż name, spokojnie można pominąć użycie this. Nie ma też problemu jeżeli zastosujemy this nadgorliwie.

...
   public Example(String exampleName) {
      name = exampleName;
   }
...

Co wiemy o this w JavaScript? Tutaj sprawa nie jest już taka prosta. W dokumentacji (najwięcej znajdziecie chyba na stronach Mozilla Developer Network) można przeczytać:

In most cases, the value of this is determined by how a function is called…

In the global execution context (outside of any function), this refers to the global object whether in strict mode or not.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#The_bind_method

I w tym momencie warto się zatrzymać. Gdyż użycie this w JS jest o wiele bardziej skomplikowane niż w Javie. Mimo to, na wielu forach często można znaleźć odpowiedź, ż this w Javie i JavaScript jest tym samym. Otóż nie. Po pierwsze w JS nie unikniemy stosowania this tak jak przedstawiłem to wcześniej w przypadku Javy. Natomiast podstawowa różnica między językami jest taka, że w JS this odnosi się do kontekstu, natomiast w Javie do instancji. Tutaj należałoby trochę więcej przytoczyć o różnicy między językami w ogóle i ich podejściu do obiektowości. Jednak nie o tym chciałem tu traktować i być może na tę chwilę wystarczy do zrozumienia tej różnicy taki przykład (pominę tu kwestię użycia strict mode, chociaż wiem, że mają one istotny wpływ na działanie this):

a = 1;
let foo = { 
   a: 2,
   withoutThis: function() {
      document.write('without this: ', a)
   },
   withThis: function() {
      document.write('with this: ', this.a)
   }
}
with this: 2
without this: 1

Zaskoczeni? W JS this odnosi się do kontekstu, czyli obiektu. W tym przypadku foo jest kontekstem dla wywołania metod withoutThis()withThis().

Złożoność użycia this w JS została świetnie opisana w dwóch miejscach, które polecam do poszerzenia wiedzy. Uznałem, że nie ma sensu rozpisywać się o tym samym, gdy mądrzejszy głowy kompleksowo poruszyły ten temat.

Używanie „this” w Javie i JavaScript. Czyli niby to samo, ale jednak coś innego. { weekly#1 }
Przewiń do góry