17 maja 2014

JavaScript - pierwsze kroki oraz pierwszy skrypt

Posted by Emnalyeriar on sobota, maja 17, 2014 in | 3 comments
Znając tylko w niewielkim zakresie podstawy PHP już na samym początku nauki JavaScript trafiłem na pewne różnice miedzy jednym a drugim językiem.
Pierwszą 'dziwną' praktyką stosowaną w JS jest immediately-invoked funcion expression (IIFE). W PHP, zmienne zadeklarowane poza funkcjami są globalne, natomiast w JS są one częścią obiektu window. Myślę, że sam nie wytłumaczyłbym tego lepiej niż ten artykuł. Główną zaletą IIFE jest brak możliwości nadpisania globalnych zmiennych tymi zadeklarowanymi wewnątrz IIFE. Niestety powoduje to również, że wewnątrz funkcji nie możemy się odnieść do zmiennej globalnej (należącej do window) ponieważ wszystkie zmienne zadeklarowane w IIFE są lokalne i dostępne tylko dla danego fragmentu kodu właśnie wewnątrz IIFE. Muszę przyznać, że przeczytałem różne artykuły, tutoriale i materiały na ten temat, a nie zdawałem sobie z tego sprawy dopóki nie próbowałem napisać własnego kodu. I tutaj moim zdaniem wychodzi jak ważne jest, aby po przeczytaniu tych wszystkich mądrych publikacji próbować napisać chociażby krótki ale własny kod, robiący cokolwiek, tak tylko dla sprawdzenia czy rozumiemy to co przeczytaliśmy. Kiedy przepisuje się kod z książki lub filmiku nie zauważa się tego typu rzeczy.
Zanim wspomnę jak poradziłem sobie z tym problemem chciałbym również napisać o sposobach deklarowania zmiennych w JS. Jeżeli przed nazwą zmiennej dopiszemy var wtedy ta zmienna jest dostępna dla danej funkcji, w której ją zadeklarowaliśmy oraz do pozostałych funkcji zagnieżdżonych w niej. Jeżeli pominiemy słowo var zmienna staje się globalna i dostępna poza funkcją. Może to wprowadzać mały zamęt i powodować, że nadpiszemy sobie niektóre zmienne więc należy zwracać na to szczególną uwagę. Bardzo pomocne przy śledzeniu zmiennych jest kolorowanie nazw zmiennych przez edytor, w którym piszemy kod.
W takim razie jak zadeklarować zmienną globalną wewnątrz funkcji? Albo poprzez pominięcie słowa var przed deklaracją funkcji lub poprzez zadeklarowanie jej do obiektu window poprzez var window.zmienna. 
Zasada ta również dotyczy deklarowania funkcji. Jeżeli zadeklarujemy funkcję poprzez function declaration czyli
 function doSomething() {}
to funkcja ładuje się przed rozpoczęciem wykonywania całego kodu co ogólnie nazywa się hoisting. Dzięki temu możemy w kodzie najpierw wywołać funkcję a dopiero później ją zadeklarować. Drugim sposobem deklaracji funkcji jest function expression:
var doSomething = function(){};
co powoduje, że funkcja staje się dostępna jedynie dla kodu napisanego poniżej jej zadeklarowania.
Należy pamiętać, że dobrą praktyką jest deklarowanie wszystkich zmiennych oraz funkcji na samym początku naszego skryptu poprzez użycie słowa var.
Więcej na temat variable scope oraz variable hoisting możecie poczytać tutaj.
Polecam również ten filmik. Przypominam również o stronie Eloquent JavaScript, z której to wiele się nauczyłem.

Na koniec chciałbym przedstawić po raz pierwszy na tym blogi (czas najwyższy) własny skrypt. Jest to prosty skrypt, który podświetla aktualnie naciskane klawisze podczas pisania oraz wypisuje średnią liczbę kliknięć na sekundę co 5 sekund.
Będzie mi niezmiernie miło jeżeli wypowiecie się na temat tego kodu, co powinienem poprawić, co zmienić, jak go udoskonalić, jakie błędy poprawić. Jeżeli również poplątałem się gdzieś w moich tłumaczeniach odnośnie zmiennych i funkcji w JS, chętnie się poprawię.
Link do skryptu.
Na koniec chciałbym wspomnieć o jeszcze jednym problemie, na który natrafiłem podczas pisania tego skryptu. Funkcja setTimeout w swoich argumentach przyjmuje funkcję, którą mam wywołać, lecz wywoływanej funkcji argumentów już przekazać niemożna. Trochę masło maślane ale mam nadzieję, że rozumiecie o co mi chodzi. Obszedłem to zastosowując kod:
var fadeOut = function(j) {
           setTimeout(function() { buttons[j].parentNode.className = "button";}, 500);
}
fadeOut(i);
Jeszcze raz zachęcam do komentowania!

3 komentarze:

  1. Co do "dziwności" JS: JavaScript w rzeczywistości pochodzi od Lispu - a więc funkcje są tam "obywatelami pierszej klasy". Połączenie lispowych idei z popularną składnią dało język, który dziś rządzi ! Podoba mi się Twoja tendencja do porównywania róznych języków. Warto pogrzebać w tym, co ludzie powymyślali - poszerza to horyzonty i uwalnia myślenie. Pozdrawiam.

    OdpowiedzUsuń
    Odpowiedzi
    1. Dzięki za komentarz! Zawsze staram się dużo szerzej spojrzeć na dany temat zanim zabiorę się za coś konkretnego. Bardzo dobrze zdaję sobie sprawę, że moja wiedza na ten temat jest mocno zawężona ale z dnia na dzień staram się dowiadywać coś nie tylko z frontendu ale z programowania ogólnie.

      Usuń
  2. ad1. jak zadeklarować zmienną globalną wewnątrz funkcji?
    dobrze jest nie ruszać zmiennych globalnych w Window. Po za twoim skryptem na stronie mogą być inne skrypty, innych autorów. Możecie sobie nawzajem namieszać. Można to zrobić tak:
    (function(){
    // twoj globalny scope
    var GLOBAL_INDEX = 1;

    var inc = function(){
    GLOBAL_INDEX++;
    }

    })();

    OdpowiedzUsuń