Tehnici Web

Laboratorul 5

(Deadline: -)

Daca nu sunteti logati exercitiile nu se mai afiseaza.

Introducere in JavaScript

Documentatie:
http://www.w3schools.com/jsref/default.asp

Declararea variabilelor

In Javascript nu este necesara precizarea tipului de date, precum in C sau alte limbaje invatate de voi pana acum. Browserul realizeaza singur identificarea tipului de date. De asemenea singur face conversiile necesare (exemplu: 3+"abc" il va converti pe 3 la string in mod automat). Variabilele pot fi declarate cu var(var a;), caz in care sunt locale pentru blocul de instructiuni in care se afla. Dar pot sa fie create si fara var insa e necesara o initializare (in momentul in care browserul intalneste de exemplu b=3, iar b nu a mai fost folosit pana atunci, este creata variabila b), si in acest caz ele vor fi globale chiar daca sunt create intr-un bloc de instrunctiuni delimitat de acolade (cum ar fi corpul unei functii sau al unei bucle while etc.). Se va vedea mai clar in exercitiul de laborator.

Instructiunile break, continue si folosirea labeled statements

Le-ati mai intalnit si in cadrul celorlalte limbaje pe care le cunoasteti. Instructiunea break fara argumente oprea bucla (while, for, do..while) in care se afla; era o iesre fortata din bucla. Instructiunea continue se folosea tot in cadrul buclelor si forta programul sa sara peste instructiunile din bucla de dupa ea (practic sa ignore instructiunile aflate sub continue), incepand imediat o noua iteratie a buclei. Se pune problema: ce facem atunci cand avem mai multe bucle? Break si continue fara argumente se refera la bucla cea mai apropiata, practic cea mai din interior bucla care le contine. Dar uneori vrem sa oprim o bucla mai din exterior. Pentru asta putem folosi etichete, ca in exemplul de mai jos.

eticheta:
instructiune_repetitiva1{
...
[eventual alte instructiuni repetitive imbricate]{
break eticheta;
}
...
}

In exemplu punem o eticheta inaintea buclei cea mai din exterior. Se presupune ca avem mai multe bucle imbricate si cu un break in cea mai din interior bucla vrem sa oprim bucla principala. In acest caz, break va fi urmat de numele etichetei pentru a indica precis la care bucla ne referim.

Functii in JavaScript

O functie se declara astfel (cu ajutorul cuvantului function):

function f (param_1, param_2,...,param_n){
..instrunctiuni..
return ceva;
}

Functiile se pot declara oriunde in cod. Nu exista function overload; daca se declara mai multe functii cu acelasi nume, va fi luata in considerare doar ultima functie cu acel nume.

Functiile sunt practic un tip de obiecte in JavaScript, deci ele au propriile metode si proprietati. Nu le voi mentiona in laborator pe toate dar puteti citi mai multe la :
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function
http://msdn.microsoft.com/en-us/library/ie/x844tc74%28v=vs.94%29.aspx
http://www.javascriptkit.com/jsref/function.shtml

Proprietatea cea mai importanta este obiectul arguments. Acesta se aseamana cu un vector (dar nu este un obiect de tip Array() ci se incadreaza intr-un tip special de obiecte). Argumentul cu numarul i poate fi accesat in cadrul corpului functiei prin arguments[i]. Obiectul arguments are si proprietatea length prin care se poate vedea cate argumente a primit functia.

Puteti citi mai multe despre acest obiect la:
http://docstore.mik.ua/orelly/webprog/jscript/ch07_04.htm

In JavaScript o functie chiar daca este declarata cu un anume numar de argumente, ea poate fi apelata de fapt cu oricate. De exemplu daca avem o functie definita cu doi parametri (exemplu function f(a,b){...}), atunci putem avea mai multe cazuri:

Cum ziceam, arguments nu e vector, dar daca totusi aveti nevoie de argumente puse intr-un vector puteti ori sa le copiati cu un for in alta variabila creata ca obiect de tip Array, ori puteti face astfel, printr-o singura instructiune:

var argumente = Array.prototype.slice.call(arguments);
Explicatia acestei constuctii. Array este de fapt o functie, functia constructor. Daca vrem sa accesam obiectul de tip vector, vom apela Array.prototype. Obiectul de tip Array are metoda slice. Metoda slice e de fapt un obiect de tip Function care isi apeleaza propria metoda call, care ii permite sa se execute pentru un alt obiect decat cel pentru care a fost definita, cu alte cuvinte obiectul de tip arguments. Daca metoda slice se plica unui obiect de tip Array, fara sa i se dea argumente, practic va genera un obiect de tip Array identic cu cel pentru care a fost apelata. Acelasi lucru se intampla si aici cand e apelata pentru arguments si creaza un vector salvat in variabila argumente, cu valorile argumentelor date functiei.

Mai multe informatii despre obiectul arguments puteti gasi la:
http://docstore.mik.ua/orelly/webprog/jscript/ch07_04.htm
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments
http://msdn.microsoft.com/en-us/library/ie/87dw3w1k%28v=vs.94%29.aspx

O alta proprietate mai folosita este length care specifica numarul de argumente cerute in definitia functiei (si nu, dupa cum am precizat mai devreme numarul efectiv de argumente ce-l poate primi functia, acestea putand fi oricate).

Codul efectiv al functiei se poate obtine sub foma unui string cu ajutorul metodei toString()

Consideram exemplul:

<script type="text/javascript">
function f( )
{
return 0;
}
document.write("codul functiei f este:<br/><code>"+f.toString()+"</code><br/>")
document.write("nr param asteptati de f: "+f.length+"<br/>")

function g(a,b)
{
return a-b;
}
document.write("nr param asteptati de g: "+g.length+"<br/>")

</script>
Va afisa:

Metoda call() se va discuta in laboratorul 6.

Tratarea erorilor

Erorile existente in JavaScript pot fi atat cele default cat si cele definite de utilizator cu ajutorul obiectului Error. "Prinderea" erorilor se realizeaza cu try{...} catch(eroare){...} finally{}. In blocul try se executa codul care se presupune ca ar putea genera erori. In caz ca o eroare este intr-adevar generata, executia codului din try e intrerupta in acel moment si se trece in blocul catch unde se poate testa tipul de eroare generat si se poate executa codul corespunzator tratarii acelei erori. Blocul finally se executa intotdeauna, indiferent daca s-a generat o eroare in blocul try sau totul a fost executat cu succes.

Atunci cand vrem sa lansam o eroare definita de noi, folosim throw impreuna cu un argument de tipul Error. Obiectul Error are doua proprietati importante name(numele erorii) si message(mesajul erorii). Throw insa poate fi apelat si cu alte tipuri de date, de exemplu un sir de caractere: throw "Eroare";.