Dogadjaji u JavaScript-u

Uvod

Događaji su pojave, koje su najčešće rezultat nečega što korisnik uradi (klik mišem, klik na tastaturi, drag and drop….), mada mogu biti izazvane i od strane sistema, browsera… Registrovanje dogadjaja na nekom HTML elementu podrazumeva vezivanje osluškivača dogadjaja (eng. event listener) za HTML elemenat i definisanje posledice tog događaja. Event listener nakon izvršenog dogadjaja poziva na akciju obrađivače događaja (eng. event handler). Event handler je callback funkcija koja se aktivira kao posledica nekog dogadjaja.

Continue reading…


Petlje i iteracije u JavaScript-u

Standardne petlje

petlja

Često se javlja potreba da se unutar programa neke linije koda izvršavaju više puta. Ovaj način izvršavanja se ostvaraju pomoću odgovarajućih upravljačkih struktura. Petlje i iteracije su osnovni gradivni element svakog programa. Standardne petlje se javljaju manje više u istom obliku u skoro svim programskim jezicima. Najkorišćenija je “for petlja”. Posebnu pažnju treba obratiti na while petlje jer postoji mogućnost da petlja usled lošeg izbora uslova postane beskonačna.

“while” petlja

While izraz se izvršava sve dok je uslov TRUE, a ukoliko nije onda se izlazi iz petlje. Ovaj tip petlje se najčešće koristi kada se ne zna tačan broj izvšenja petlje. U slučaju da uslov na samom početku nije ispunjen, petlja se ne izvršava ni jednom. Pre ulaska u petlju vrši se inicijalizacija promenljivih koje će biti korišćene bilo u uslovu, bilo u telu petlje. U telu petlje se nalazu kod koji formira uslov za ostanak u petlji.

Ovaj tip je nazvan “pre-test loop” jer se uslov izvršava pre bloka sa izrazom.


Continue reading…

Šta su JavaScript closure?

Definicija i karakteristike

closure in debiger

Poznata je činjenica da kada se završi funkcija, sve njene lokalne promenljive pokupi garbage collector i one prestaju da postoje u memoriji. Medjutim to nije slučaj za funkciju koja unutar sebe sadrži closure funkciju.

Closure su funkcije koje imaju pristup promenjivima koje se nalaze u domenu druge funkcije. Ovo se najčešće postiže ugradjivanjem funkcije unutar druge funkcije (čime se definiše “scope chain”), nakon čega closure dobija sposobnost da zapamti referencu na promenjive iz parent domena.

Treba napomenuti da se promenjive spoljne funkcije ne brišu po izvršavanju same funkcije, već se čuvaju u memoriji da bi bile dostupne closure funkciji. Nakon izvršenja closure funkcije, zatvara se i spoljna funkcija (odatle i naziv “closure“). Dok god se closure ne izvrše, JavaScript će čuvati i potrebne promenjive iz domena drugih funkcija, stoga one zauzimaju više memorije nego obične funkcije. Preterano korišćenje closure može da dovede do povećenja potrošnje memorije. Najnoviji JavaScript engine uspevaju da delimično oslobode zarobljenu memoriju, ali je i dalje stoji preporuka da se bude pažljiv pri korišćenju closure.

U sklopu debuger-a ugradjenog u browseru, može da se vidi closure izraz i koja je vrednost pormenjive “zapamćena” (pogledaj sliku).

Primer standardne closure f-je

Funkcija b() je ugnježdena unutar funkcije a() i duž “scope chain” potražuje promenjivu iz funkcije a(), stoga je ona klasičan primer closure funkcije.

Nije svaka ugnježdena funkcija i closure

Ukoliko unutrašnja funkcija ne koristi promenjivu iz spoljnih funkcija u kojim se nalazi (duž “scope chain”), to onda nije closure. Pogledaj naredni primer:

Closure pamti promenjive iz spoljne funkcije čak iako je spoljna fukcija izvršena

Poznato je da se nakon korišćenja naredbe return prekida izvršenje funkcije i postojanje njenih promenjivih u privremenoj memoriji. Medjutim “Closure” pamti promenjive iz spoljne funkcije čak iako je vratila neku vrednost sa return.

Closure “pamti” referencu na koju ukazuje promenjiva

Kada se kaže da “closure funkcija” ima pristup promenjivoj pod tim se misli da ima pristup odredjenom mestu u memoriji na koju ukazuje ta promenjiva tj. njenoj referenci u trenutku pozivanja “clousure funkcije“. Ukoliko se na tom mestu u memoriji tj. referenci menja vrednost, clousure će uvek uzeti najnoviju trenutnu vrednost. U narednom primeru se vidi kako unutrasnja funkcija “pamti” referencu i koristi trenutnu vrednost u memoriji.

Redeklarisanje promenjive

Ako nakon definisanja clousure, promenjivoj koja je potrebna closure dodelimo neku drugu referencu (mesto u memoriji koje čuva neku vrednost), clousure će da koristi referencu koja je bila u opticaju u trenutku definisanja clousure. U sledećem primeru, funkcija sayHello() u trenutku definisanja “pamti” referencu na globalnu promenjivu “myName” (“Dragoljub”). Pa iako “myName” menja referencu koja sada sadrži vrednost “Marko”, closure i dalje koristi vrednost “Dragoljub”.

Medjutim to ne znači da closure pamti prvu definisanu vrednost neke promenjive, već pamti definisanu vrednost promenjive u trenutku definisanja closure. Pa tako u sledećem primeru funkcija vraća “Marko”

NAPOMENA:
Kada se koristi ključna reč “new” za kreiranje objekta unutar neke spoljne funkcije, TO NE KREIRA CLOSURE i nova funkcija nema referencu na lokalnu promenjivu spoljne fukncije kao closure.

Continue reading…


Eksponencijalni operator **

Sintaksa operatora

Sve do ES2016 standarda u JavaScriptu nije postojao eksponencijalni operator, već se koristila metoda Math.pow. Sada operator “**” vraća rezultat stepenovanja osnove (prvi operand) sa eksponentom (drugim operandom):

<strong>x<sup>y</sup></strong> = Math.pow(x, y) = <strong>x**y</strong>

Primer

Primer

Pored ovo standardnog operatora možemo da ga koristim uz operator “=”:

NAPOMENA:
U JavaScriptu nije dozvoljeno pisati tzv. dvosmisleni kod, stoga sledeći primer vraća grešku:

Stoga je neophodno jasno dati do znanja koja operacija ima prednost:

ili


Modularno programiranje sa ES6

Karakteristike ES6 modula

es6 modul

Sa novom verzijom JavaScript-a ES6 dolazi integrisana podrška za modularno programiranje.

  • Podržava module koji se smeštaju u datoteke – jedan modul po datoteci
  • Moduli su jedinstveni primerci, svaki modul se izvršava samo jednom (singleton model).
  • ES6 moduli mogu da rade i sinhrono i asihrono.
  • Podržava “cyclic dependencies”.
  • Sintaksa je još kompaktnija od CommonJS
  • ES moduli imaju statičku strukturu. Pošto je struktura modula nepromenjiva, često je dovoljno da se pregleda kod i shvati šta se gde importuje. Ovo nije slučaj kod dinamičke strukture, gde je često potrebno da se kod izvrši da bi se videlo šta se importuje. Eventualne greške mogu da se nadju i u vreme kompajliranja (sa modul bundler-om), jer se sve radnje vezane za import i export modula odredjuju u tom trenutku.
  • Svi uvezeni elementi su nepromenjivi iz modula koji importuje. Svaka operacija dodeljivanja vrednosti uveženom elementu bi prouzrokovala grešku (TypeError).
  • ES6 se ne pravi kopiju svojstva već deli vezu na to svojstvo. Ovo važi čak i za deljenje primitivnih svojstava (“broj” ili “string”). U narednom primeru vidimo da ukoliko matični modul promeni vrednost deljenog svojstva (promena je izvršena metodom iz matičnog modula!), modul koji je importovao to svojsto “vidi” tu promenu.
    PRIMER
    proracun.js

    main.js

    Importujemo sve elemente koji su eksportovani iz modula “proracun.js”

    Ako bi se sada koristila promenjiva “brojač” u nekom “trećem” modulu imala bi vrednost 2.

Continue reading…


Modularno programiranje – eksterna sintaksa (AMD & CommonJS)

Uvod

Externe sintakse nisu JavaScript biblioteke, već odgovarajuće specifikacije i konvencije za definisanje modula. Eksterna sintaksa može da se koristi jedino uz pomoć modul loader-a koji joj “udahnu život”. Ako modul loader podržava sintaksu to znači da unutar sebe sadrži ugradjene metode koje su prethodno zamišljene da se koriste kroz odredjenu sintaksu.
Prednost korišćenja ovih eksternih sintaksi u odnosu na native ES5 modul patern je ta što ne zagadjuje globalni domen nazivima modula i što je omogućen rad dependencies menadžera.

  • Asynchronous Module Definition (AMD) kao što mu i samo ime kaže, podržava asihrono učitavanje modula što je pogodno za rad sa modulima u browser-u.
  • CommonJS učitava module sinhrono i zbog toga se najčešće koristi za rad sa modulima na serverskoj strani u okruženju node.js. Iako nije planiran za rad u browser-u, uz pomoć “modul bundler-a” je moguće da prilagoditi CommonJS radu u browser-u.
  • Universal module definition (UMD) je kompatibilan i sa AMD i sa CommonJS definicijom i koristi se uglavnom ukoliko ima potrebe da se isti modul učitava na serveru i u browser-u.

OBJAŠNJENJE:
CommonJS, AMD ili UMD nisu JavaScript biblioteke. To su organizacije za standardizaciju, kao što je ECMA (definiše specifikaciju jezika za JavaScript) ili W3C (definiše JavaScript web API, kao što su DOM ili DOM događaji). Cilj CommonJS ili AMD sintaksi je definisanje API-ja za rad sa modulima.

Continue reading…


Modularno programiranje sa ES5

Uvod

es5

ES5 verzija JavaScript-a nema podršku za module, ali bez obzira na to je moguće držeći se odredjenih principa napraviti aplikacije u maniru modularnog programiranja. Module sa svojim enkapsuliranim kodom kreiramo koristeći “Immediately-Invoked Function Expressions” ili sa konstruktor funkcijom. API modula koji treba da bude javan jednostavno vratimo unutar funkcije sa rezervisanom reči return. Ovo je jednostavan šablon i može se primeniti bilo gde bez dodatnih biblioteka. U okviru jednog fajla je moguće definisati više modula.

Pored navedenih prednosti ovaj pristup ipak ima i svojih mana:

  • “zagadjivanje” globalnog domena nazivima modula, mada je body modula skriven korišćenjem funkcija (IIFE) u lokalni domen.
  • “ručno” odredjivanje redosleda učitavanja modula a redosled učitavanja modula može biti prilično komplikovan kod velikih i kompleksnih aplikacija.
  • nije moguće asihrono učitavanje

Ovi šabloni nisu savršeni i imaju svoje mane ali bez obzira na mane, kod je razumljiviji jer je bolje organizovan.

Continue reading…


Uvod u modularno programiranje

Karakteristike modularnog programiranja

modularno programiranje kocka

Modularni koncept programiranja je trenutno jedan od najzastupljenijih koncepata u modernom programiranju sa Javascript-om. Zasniva se na razbijanju jedne velike aplikacije na manje, enkapsulirane, nezavisne delove koda – module. Cilj modularnosti jeste da se smanji kompleksnost prema principu “podeli pa vladaj”. Najznačajnije prednosti modularnog programiranja su:

  • preglednija i razumljivija aplikacija
  • lakše kontrolisanje domena promenjivih
  • sprečeno “zagadjenje globalnog domena”
  • ponovna upotrebljivost koda
  • mogućnost rada na istom projektu više različitih timova ili programera koji rade odvojene manje zadatke.
  • lakše debagovanje

Continue reading…


Pregled ugradjenih dogadjaja u JS

Događaji sa mišom

Event Opis DOM
onclick The event occurs when the user clicks on an element 2
oncontextmenu The event occurs when the user right-clicks on an element to open a context menu 3
ondblclick The event occurs when the user double-clicks on an element 2
onmousedown The event occurs when the user presses a mouse button over an element 2
onmouseenter The event occurs when the pointer is moved onto an element 2
onmouseleave The event occurs when the pointer is moved out of an element 2
onmousemove The event occurs when the pointer is moving while it is over an element 2
onmouseover The event occurs when the pointer is moved onto an element, or onto one of its children 2
onmouseout The event occurs when a user moves the mouse pointer out of an element, or out of one of its
children
2
onmouseup The event occurs when a user releases a mouse button over an element 2

Događaji sa tastaturom

Event Opis DOM
onkeydown The event occurs when the user is pressing a key 2
onkeypress The event occurs when the user presses a key 2
onkeyup The event occurs when the user releases a key 2

Continue reading…


Pregled svojstava event objekta

Uvod

Kada god se desi neki dogadjaj (eng. event), javascript smešta sve relevantne podatke vezane za dogadjaj u “event objekat”, npr. gde je bio mouse pointer, kojim dugmetom je kliknuto, koji element je kliknut… Ovaj objekat se uvek prosledjuje callback funkciji, pa stoga callback funkcija ima pristup svim podacima smeštenim u njemu. Podacima pristupamo preko svojstva event objekta. U ovom članku su okupljena sva svojstva Event objekta.

Glavna svojstva event objekta

Svojstvo objekta Svojstvo objekta Opis DOM
bubbles Returns whether or not a specific event is a bubbling event 2
cancelable Returns whether or not an event can have its default action prevented 2
currentTarget Returns the element whose event listeners triggered the event 2
defaultPrevented Returns whether or not the preventDefault() method was called for the event 3
eventPhase Returns which phase of the event flow is currently being evaluated 2
isTrusted Returns whether or not an event is trusted 3
target Returns the element that triggered the event 2
timeStamp Returns the time (in milliseconds relative to the epoch) at which the event was created 2
type Returns the name of the event 2
view Returns a reference to the Window object where the event occured 2

Svojstva vezana za rad sa mišem

Svojstvo objekta Opis DOM
altKey Returns whether the “ALT” key was pressed when the mouse event was triggered 2
button Returns which mouse button was pressed when the mouse event was triggered 2
buttons Returns which mouse buttons were pressed when the mouse event was triggered 3
clientX Returns the horizontal coordinate of the mouse pointer, relative to the current window, when the
mouse event was triggered
2
clientY Returns the vertical coordinate of the mouse pointer, relative to the current window, when the
mouse event was triggered
2
ctrlKey Returns whether the “CTRL” key was pressed when the mouse event was triggered 2
detail Returns a number that indicates how many times the mouse was clicked 2
metaKey Returns whether the “META” key was pressed when an event was triggered 2
relatedTarget Returns the element related to the element that triggered the mouse event 2
screenX Returns the horizontal coordinate of the mouse pointer, relative to the screen, when an event was
triggered
2
screenY Returns the vertical coordinate of the mouse pointer, relative to the screen, when an event was
triggered
2
shiftKey Returns whether the “SHIFT” key was pressed when an event was triggered 2
which Returns which mouse button was pressed when the mouse event was triggered 2

Svojstva vezana za rad sa tastaturom

Svojstvo objekta Opis DOM
altKey Returns whether the “ALT” key was pressed when the key event was triggered 2
ctrlKey Returns whether the “CTRL” key was pressed when the key event was triggered 2
charCode Returns the Unicode character code of the key that triggered the onkeypress event 2
key Returns the key value of the key represented by the event 3
keyCode Returns the Unicode character code of the key that triggered the onkeypress event, or the Unicode
key code of the key that triggered the onkeydown or onkeyup event
2
location Returns the location of a key on the keyboard or device 3
metaKey Returns whether the “meta” key was pressed when the key event was triggered 2
shiftKey Returns whether the “SHIFT” key was pressed when the key event was triggered 2
which Returns the Unicode character code of the key that triggered the onkeypress event, or the Unicode
key code of the key that triggered the onkeydown or onkeyup event
2

Svojstvo vezano za promenu fokusa

Svojstvo Evernt objekta Opis svojstva DOM
relatedTarget Returns the element related to the element that triggered the event 3

Svojstva vezana za animaciju

Svojstvo Evernt objekta Opis svojstva DOM
animationName Returns the name of the animation
elapsedTime Returns the number of seconds an animation has been running

Svojstva vezana za tranziciju

Svojstvo Evernt objekta Opis svojstva DOM
propertyName Returns the name of the CSS property associated with the transition
elapsedTime Returns the number of seconds a transition has been running

Svojstva vezana za scroll

Svojstvo Evernt objekta Opis svojstva DOM
deltaX Returns the horizontal scroll amount of a mouse wheel (x-axis) 3
deltaY Returns the vertical scroll amount of a mouse wheel (y-axis) 3
deltaZ Returns the scroll amount of a mouse wheel for the z-axis 3
deltaMode Returns a number that represents the unit of measurements for delta values (pixels, lines or pages) 3

Svojstvo vezano za keširanje

Svojstvo Evernt objekta Opis svojstva DOM
persisted Returns whether the webpage was cached by the browser  

Svojstvo vezano za hash poziciju na strani

Svojstvo Evernt objekta Opis svojstva DOM
newURL Returns the URL of the document, after the hash has been changed
oldURL Returns the URL of the document, before the hash was changed