Andrise programmeerimisalane WIKI
Keele struktuurid
Javascripti süntaks ning keele struktuurid on praktilised identsed C, Java, PHP ja muude sarnaste programmeerimiskeeltega. Nii tsüklid kui tingimuslaused peaksid seega olema kõigile varem taolisi keeli kasutanutule tuttavad. Erandiks oleks ehk vaid for..in, mis tuleneb peamiselt JavaScripti prototüübilisest ülesehitusest ning mida seetõttu muudes keeltes võibolla päris sellisel kujul ei esine.
Tsüklid
Tsükkel ehk korduslause on programmiosa, mis kordab määratud lausejada senikaua kuni etteantud tingimus saab täidetud. Näiteks kui on vaja mingisugust tegevust korrata teatud kindel arv kordi (selleks sobib hästi for tsükkel) või kuni kindel tingimus saab täidetud (while ja do..while).
Tüklite peamiseks probleemiks on, et tsükli täitmise ajal on kogu programmi kontroll tsükli käes, sh. programmi brauseriaknas täitmise korral ka kontroll brauseri üle. See tähendab, et kui mingi tsükkel töötab liiga kaua (näiteks lõputu tsükkel), siis reeglina muutub brauseri aken mittevastavaks. Eesolevalt veebilehelt ei saa ära navigeerida, ei saa brauseri akent sulgeda, ei saa skripti tööd peatada. Tegevus võib lõppeda terve arvuti kinnijooksmisega, kui brauseris jooksev skript kulutab ära kogu arvuti CPU ning mälu limiidid. Seega tuleb hoolega jälgida, et ei tekiks programmis võimalust sarnase olukorra tekkimiseks.
Lõputu tsükli näide:
while(1){}
Tsüklit täidetakse seni, kuni 1 ei ole enam tõene (1==0), seda ei juhtu paraku aga kunagi.
for
for tsükkel on loendajaga tsükkel. Tsüklit täidetakse seni, kuni loendajaga seotud tingimus enam ei kehti (n: loendaja saab suuremaks lubatud väärtusest). Tsükkel kasutab järgmist süntaksit:
for (lähtesta; tingimus; muutus) { // korda kuni 'tingimus' enam ei kehti }
Näiteks:
for (i=0; i<array.length; i++) { alert(array[i]); }
Eelmine näide ei ole tegelikult for tsükli iseloomustamiseks eriti hea. Esiteks on muutuja i ise lähtestamata - sellisel juhul lülitatakse see globaalsesse skoopi, mis võib viia ootamatute tulemusteni. Teiseks tuleb tsükli iga korduse puhul leida üles massiivi suurus (suurim indeks+1). Veidi paremini koostatud tsükkel oleks selline:
for(var i=0, len=array.length; i<len; i++){ alert(array[i]); }
Ja kolmas implementatsioon oleks (eeldame et massiivi kõik liikmed on tõesed väärtused):
for (var i=0; item=array[i]; i++) { alert(item); }
Sellisel juhul pole massiivi pikkust vaja üldse teada. Tsükkel kestab seni, kuni massiivi elemendi väärtus ei ole tõene.
for..in
for..in struktuur on etteantud massiiviga seotud tsükkel, mis väljastab ükshaaval massiivi kõik indeksid.
for (indeks in massiiv) { // väljastab ükshaaval kõik indeksid }
Näiteks:
for (var a in array) { alert(array[a]); }
Kahjuks ei ole sellisel viisil väljastatud indeksite järjestus garanteeritud - massiivi koheldakse for..in tsüklis objektina, aga objekt kujutab endast sorteerimata kogumit. Samuti võib tekkida probleeme, kui tegu pole lihtsa massiiviga - kuna operaator in on mõeldud objektidest (JavaScripti järgi on massiiv eritüübiline objekt) võtmete leidmiseks, võib tsükkel seetõttu väljastada lisaks numbrilistele indeksitele ka muid konkreetse objekti juurde käivaid võtmeid.
var array = [1,2,3]; array.suvaline = function(){ // lisame massiivile meetodi nimega suvaline alert(this.length); }; for(var a in array){ alert(a); }
Väljastab:
0 1 2 suvaline
while
while tsükkel on eelkontrolliga tsükkel, mis tähendab, et tsüklit täidetakse seni kuni tsüklitingimus võtmesõna while järel ei ole enam tõene. while tsükli süntaks on järgmine:
while (tsüklitingimus) { // korda kuni 'tingimus' enam ei kehti }
do
do tsükkel on järelkontrolliga tsükkel - tsüklit täidetakse seni kuni tsüklitingimus võtmesõna while järel ei ole enam tõene. Tsükkel erineb eelkontrolliga while tsüklist selle tõttu, et tsüklit täidetakse sama tsüklitingimuse korral ühe korra rohkem kuna kontroll ei ole mitte tsükli alguses, vaid lõpus. while tsükkel mittetõese tingimuse korral ei rakendu, aga do tsükkel rakendub vähemalt korra. Tsükli süntaks on järgmine:
do { // korda kuni 'tingimus' enam ei kehti } while (tsüklitingimus);
Tingimuslaused
Tingimuslaused võimaldavad käivitada või vahele jätta tegevusi vastavalt sisendparameetrite väärtustele.
if
Tingimuslause, mis sõltuvalt tingimusavaldise tõeväärtusest kutsub esile lisatud lausejadade täitmise või jätab need vahele. Tingimusavaldis if lauses peab asuma sulgudes.
if (tingimus) { // täida, kui tingimus on tõene } else { // täida kui tingimus ei ole tõene }
else lausejada ei ole kohustuslik.
JavaScriptis puudub programmeerimiskeelte PERL elsif, PHP elseif ja Python elif käsklustele sarnane tingimuslause. Selle asemel võib kasutada if tingimuslausete liitmist või hoopis käsklust switch.
if tingimuslausete liitmine erinevate väärtuste kontrollimiseks:
if (a==0) { // täidetakse juhul kui a on võrdne väärtusega ''0'' } else if (a<10) { // täidetakse juhul kui a on väiksem kui ''10'' } else { // täidetakse kõikidel muudel juhtudel }
Ternaarne tingimuslause
Ternaarne operatsioon on kolme operaatori funktsioon if..else tingimuslause esitamiseks lühivormina. Tingimuslause argumendid on üks loogiline muutuja (tingimus) ja kaks lauset ning selle tagastusväärtuseks on esimese lause tagastusväärtus, kui tingimus on tõene, ja teise lause tagastusväärtus, kui tingimus on väär. Täitmisele läheb ainult see lause, mis mille tulemus kuulub tagastamisele, teine lause jääb rakendumata. Operaatoriteks on sümbolid ? ning :.
tingimus?tagastus_tõese_tingimuse_korral:tagastus_väära_tingimuse_korral;
var a = b>1?2:3;
Juhul kui muutuja b on näites suurem kui 1, saab muutuja a väärtuseks 2, vastasel juhul aga saab muutuja väärtuseks 3.
switch
switch on valikulause mitmevariandiliste valikute realiseerimiseks.
switch (väärtus) { case tingimus: //täida kui tingimus vastab sisendväärtusele break; //keelab järgnevaid tingimusi proovida default: //täida kui ükski tingimus ei olnud sisendväärtuse suhtes tõene (ei ole kohustuslik) }
Valiklause switch puhul leitakse esiteks võtmesõna switch järel oleva avaldise väärtus. Seejärel võrreldakse saadud väärtust võtmesõnade case järel olevate avaldiste väärtustega ning kui väärtused on võrdsed, täidetakse järgnev lausejada. Käsklus break lõpetab valiklause täitmise. Juhul kui break puudub, täidetakse ka järgmine avaldis, hoolimata selle case kontrollväärtusest.
Kui ei leita ühtegi tõest case tingimust, täidetakse (juhul kui on) valikuline default lausejada.
switch (a) { case 0: alert('a on 0'); break; case 1: alert('a on 1'); break; case 2: alert('a on 2'); break; default: alert('a ei ole 0 ega 1 ega 2'); }
Veatöötlus
JavaScript pakub arendajale mitmeid võimalusi tekkivaid vigu hallata. Üheks selliseks võimaluseks on näiteks sündmusele onError oma sündmuse haldaja lisamist, mis võimaldab „ära lõigata“ kõik tekkivad vead. Mõistlikum oleks siiski läheneda vigadele ükshaaval.
try..catch
try..catch on lausestruktuur, mis võimaldab proovida mingi lausejada täitmist (try) ning kui selles esineb viga, tühistatakse kõik lausejada tegevused ja täidetakse veatöötluse käsklused (catch).
try{ // Proovi mingeid tegevusi } catch (E) { // Juhul kui tegevused päädisid vea ilmnemisega, käivita antud blokk // muutuja E sisaldab endas infot tekkinud vea kohta }
Näiteks:
try{ var a = tundmatu_suurus; // tundmatu suurus on defineerimata }catch(E){ alert(E.message); }
Väljundiks on:
tundmatu_suurus is not defined
throw
throw lõpetab programmi täitmise ja väljastab veateate. Saab kasutada koos try..catch struktuuriga, kus try lausejadas olev tingimus käivitab throw ja lõpetab sellega lausejada täitmise.
throw "veateade";
Näiteks:
try{ if(1!=2){ throw new Error("1 ja 2 ei ole võrdsed!"); } } catch (E) { alert(E.message); }
Väljund:
Viga! 1 ja 2 ei ole võrdsed!
Muud lausestruktuurid
label
Märgend label võimaldab ära tähistada programmiosi, millele saab viidata lausetega break ning continue. Märgendiks võib olla suvaline nimetus mis ei kuulu reserveeritud sõnade hulka. Oluline on, et label omab tähendust vaid vahetult märgendile järgnevas lauses, milleks võib muu hulgas olla ka {} blokk. Muudest programmiosadest label blokki välja kutsuda ei saa - selle poolest erineb märgend näiteks basicu GOTO lausest.
Käsklus break katkestab märgendile järgneva lause ning programm saab oma tööga edasi minna. continue aga viib programmi täitmise märgendi juurde tagasi, moodustades sellega omamoodi tsükli.
Märgendite kasutamine ei ole siiski väga soovituslik programmeerimisstiil, kuna võib muutuda raskesti jälgitavaks ning seega võivad vead kergemalt sisse sattuda.
var loendur = 0; kordus: { // märgend while(1){ // Lõputu tsükkel alert(loendur); loendur++; if(loendur>10) // juhul kui loendur on suurem kui 10, lõpetame märgendiga tähistatud lausejada break kordus; } }
break
Katkestuslause break [label]; peatab tsükli, valikulause switch või märgendlause label täitmise. Katkestuslause peab asuma katkestatava lausejada sees. Parameeter label on valikuline ning kasutatav juhul, kui soovitakse lõpetada märgendatud lausejada täitmist (vt. label).
while(1){ break; //katkestab tsükli while }
continue
Jätkamislause continue [label]; sarnaneb katkestuslausele break, aga kui break katkestab hetke lausejada täitmise üldse, siis continue lõpetab ainult hetkel käimasoleva iteratsiooni ning läheb järgmise iteratsiooniga edasi. Võimalik on niiviisi katkestada tsükleid ning juhul kui valikuline parameeter label on määratud, ka märgendlauseid.
for(var i=0; i< len; i++){ alert(i); // Seda rida täidetakse nii palju kordi, kui on muutuja len suurus. continue; // Liigutab programmi täitmise järgmise for iteratsiooni juurde alert(i); // Seda rida ei täideta kunagi }
function
Loob uue funktsiooni etteantud parameetritega, täpsemalt loe funktsioonide peatükist.
function a(x){ alert(x); }
return
return [väärtus]; määrab ära funktsiooni poolt tagastatava väärtuse, milleks on valikulise parameetri väärtus väärtus. Juhul kui parameeter väärtus pole määratud, käitub lause sarnaselt lausele break tsüklite korral ning funktsiooni töö lõpetatakse, tagastades väljastuskohta eriväärtuse undefined (sama väärtus tagastatakse ka juhul, kui return lause puudub üldse).
function liida(a, b){ return a+b; }
var
var deklareerib muutuja hetke skoobis ning kui on vastavalt määratud, siis ka lähtestab. var m1 [= v1], m2 [= v2],… mn [= vn];, kus mx on muutuja ning vx on väärtus.
var a; var a=0; var a=0, b=7;
var lausega tuleb kindlasti jälgida skoopi - JavaScript erinevalt teistest C sarnase süntaksiga programmeerimiskeeltest ei oma mitte blokk-, vaid funktsiooni skoopi. Ehk et var lause omab muutuja kohta tähendust ühe korra globaalses skoobis ning siis veel korra igas funktsioonis eraldi. Juhul kui skoobis on deklareeritud muutuja võtmesõnaga var, muudab see muutuja lokaalseks terve skoobi ulatuses. Loe lähemalt funktsioonide peatükist.
var mängib rolli terve skoobi suhtes.
var a = 1; function abc(){ alert(a); // undefined var a = 2; alert(2); // 2 }
Lausete {…} blokk ei moodusta omaette skoopi.
var a=1; { var a=2; } alert(a); // väljastab 2
Skoobi saab luua anonüümse funktsiooniga.
var a=1; (function(){ var a=2; })(); alert(a); // väljastab 1
with
Võtmesõna with lühendab objekti jada lausejadas - võimalik on näiteks kasutada pika nimetuse objekt.alamobjekt.veel.muutuja asemel lühikest nimetust muutuja.
Seega saab kirjutada
document.getElementbyId('elemendi_id').style.color = 'red'; document.getElementbyId('elemendi_id').style.background = 'black';
asemel
with(document.getElementbyId('elemendi_id').style){ color = 'red'; background = 'black'; }
Juhul kui objektil on width blokis oleva muutuja nimeline omadus olemas, siis with kasutab muutujana just sedasama omadust, isegi kui väljaspool blokki eksisteerib sama nimega muutuja. Kui aga vastava nimega omadust pole, käsitletakse muutujat aga tavalise muutujana.
var a = 1; var b = 1; var c = {a:1}; with(b){ a++; b++; } alert(a); // 1 alert(b); // 2 alert(c.a); // 2
Seda võtmesõna ei tasu siiski mitte kunagi kasutada, kuna with on lõppematu vigade allikas. Probleem seisneb selles, et with järgi olev lausejada jagab ümbritsevat skoopi ning seega ka kõiki kättesaadavaid muutujaid. Programmikoodi lugedes pead täpselt teadma, et kas color on document.getElementbyId('elemendi_id').style juurde käiv element või hoopis mõni globaalne muutuja. Ei ole võimalik üheselt aru saada, millised muutujad lausejadas tulevad väljast ja millised seotud objekti juurest. Vigade avastamise ja likvideerimise teeb see ülimalt raskeks.
Mõistlikum oleks kasutada objekti omistamist uuele muutujale (muutujaid omistades ei looda kunagi omistatavast muutujast koopiat vaid antakse uuele muutujale viide vana juurde, seega omistamisega täiendavat ressursikulu ei kaasne).
var o = document.getElementbyId('elemendi_id').style; o.color = 'red'; o.background = 'black';
Käidud rada: • operaatorid • matemaatika • sissejuhatus • funktsioonid • andmetueuebid • xmlhttprequest • aeg_ja_kuupaev • bitioperatsioonid • regulaaravaldised • keele_struktuurid