27.4.2015 Aulikki Hyrskykari Antti Sand
o Edellinen luento Taustaa Perusteita Tulkattava kieli työkalut selaimessa Operaattorit Tietotyypit Perustietotyypit Lauseet Oliot o Tällä kertaa: JavaScript Built-in oliot Funktiot
o Tiedonpaketoija-oliot (data wrappers) perustietotyyppisen muuttujan voi määritellä "tiedonpaketoija-olioksi jos tarpeen käsitellä muuttujaa oliona, esim. tarvitaan metodeja Object, Number, Boolean, String, Array ja Function o Apuväline-oliot Math, Date ja RegExp tuovat mukanaan monia käyttökelpoisiin tietoihin ja toimintoihin o Virheoliot niiden avulla saadaan tietoa avuksi odottamattomista tilanteista selviytymiseen
o Kaikkien JavaScript-olioiden äiti var o1 = new Object(); var o2 = {; // o1 ja o2 samanlaisia olioita o Tyhjälläkin oliolla joukko metodeja, esim. o1.tostring() // palauttaa olion merkkijonoesitysmuodossa o1.valueof // palauttaa olion itsensä
o Jos luvulle esimerkiksi halutaan määritellä metodeja, se voidaan esitellä perustietotyypin number sijasta olioksi Number tofixed(), palauttaa luvun desimaalipiste esitymuotoisena merkkijonona toexponential(), palauttaa luvun eksponenttinotaation merkkijonona jos näille funktioille antaa parametrin, se määrittelee käytetyn tarkkuuden var n = new Number(15.565); var mja1 = n.tofixed(1); var mja2 = n.tofixed(); var mja3 = n.toexponential(3); // = 15.6 yksi desimaali // = 16 pyöristys kokonaisluvuksi // = "1.556e+1"
o Number oliolla myös ominaisuuksia esim. MAX_VALUE suurin esitettävissä oleva luku MIN_VALUE pienin esitettävissä oleva NEGATIVE_INFINITY = -Infinity POSIVITIVE_INFINITY = Infinity o Kutsutaan suoraan built-in oliota käyttäen esim. var luku1 = Number.MAX_VALUE; var luku2 = Number.MIN_VALUE; var luku3 = Number.MIN_VALUE*1000; // 1.7976931348623157e+308 // = 5e-324 // = 4.94e-321
var b = new Boolean(totuusarvo); o On tärkeätä muistaa, että konstruktori luo Boolean-olion, ei perustietotyyppiä boolean: typeof b on siis object olion sisältämän boolean-arvon voi kysyä valueof-metodilla: typeof b.valueof() on boolean o Jos ei tyhjä olio konvertoidaan boolean arvoksi, sen arvo on aina tosi var b1 = new Boolean(true); var b2 = new Boolean(false); if (b1) lause1; else lause2; // suoritetaan lause1 if (b2) lause1; else lause2; // suoritetaan lause1 if (b1.valueof()) lause1; else lause2; // suoritetaan lause1 if (b2.valueof()) lause1; else lause2; // suoritetaan lause2 o Huomaa siis, että vaikka konstruktorille annetaan parametriksi false, Boolean-olion arvo on true samoin käy vaikka parametrina annettaisiin mikä tahansa arvo joka konvertoituu totuusarvoksi false
o Muista siis, että vaikka konstruktorille annetaan parametriksi false, Boolean-olion arvo on true samoin käy vaikka parametrina annettaisiin mikä tahansa arvo joka konvertoituu totuusarvoksi false o Boolean-olioilla ei paljon käyttöä, koska sillä ei ole omia metodeita, eikä ominaisuuksia (vain perityt) o Jos Boolean-kostruktoria kutsuu ilman new operaattoria saa aikaan parametrin muutoksen boolean-perustietotyypiksi var b1 = Boolean(true); var b2 = Boolean(false); var b3 = Boolean(10); var b4 = Boolean(0); var b5 = Boolean(null); var b6 = Boolean("false"); // b1 = true // b2 = false // b3 = true // b4 = false // b5 = false // b6 = true
o Taulukko on JavaScriptissä toteutettu oliona järjestetty joukko arvoja, joihin voi viitata joko nimellä tai indeksillä voidaan luoda useammalle tavalla var taulu1 = new Array(alkio0, alkio1,..., alkion); var taulu2 = [alkio0, alkio1,..., alkion]; o Jos taulukko luodaan antamatta sille sisältöä, voi sen pituuden kuitenkin määrittää taulukkoa jo luotaessa var taulu3 = new Array(3); // taulukko-olio, sisältää kolme alkiota sisältävä var taulu4 = Array(3); // kolme alkiota sisältävä taulukko-olio kuten // edellä, vaikka ei käytettykään operaattoria new var taulu5 = []; taulu3.length = 3; taulu6[0]=alkio1; taulu6[1]=alkio2; taulu6[2]=alkio3;
o Moniulotteiset taulukot luodaan sisäkkäisten taulukoiden avulla solu edelleen taulukko o Mitä seuraava koodinpätkä kirjoittaisi HTML-dokumenttiin? var imax = 5; var i, j; // silmukkamuuttujat var matriisi = new Array(iMax + 1); // taulukon pituudeksi imax+1, // (indeksointi lähtee nollasta) for (i = 1; i <= imax; i++) { // kullekin taulukon riville matriisi[i] = new Array(iMax + 1); // Luo taulukon sarakkeet for (j = 1; j <= imax; j++) { // täytetään taulukko matriisi[i][j] = i * j; document.write(matriisi[3][4] + <br /> ); document.write(matriisi[5][2] + <br /> ); document.write(matriisi[1][4] + <br /> ); 12 10 4
o Array ominaisuus length palauttaa taulukon pituuden o Array oliolle määriteltyjä metodeja, esim. indexof() - etsii taulukon alkion ja palauttaa sen indeksin pop() - palauttaa viimeisen alkion ja poistaa sen taulukosta push() - lisää uuden alkion taulukon loppuun ja palauttaa taulukon uuden pituuden reverse() - kääntää taulukon alkiot päinvastaiseen järjestykseen shift() - palauttaa ensimmäisen alkion ja poistaa sen taulukosta sort() - lajitteleen taulukon unshift() - lisää elementin taulukon alkuun ja palauttaa taulukon uuden pituuden var hedelmat = new Array("omena", "appelsiini", "banaani", "mango"); var i = hedelmat.indexof("omena"); // i:n arvo 0 hedelmat.sort(); // hedelmät aakkosjärjestyksesä var j = hedelmat.indexof("omena"); // j:n arvo 3 var k = hedelmat.indexof( rypale ); // k:n arvo on -1 o Lisää taulukko-olion metodeja: concat(), every(), filter(), foreach(), join(), lastindexof(), map(), slice(), some(), sort(), splice()
o Date muuttujaan voi tallentaa päiväyksen ja ajan o Ajan voi ilmaista oliomuuttujaa luodessaan antamalla konstruktorille kokonaisluku: millisekunteja - tulkitaan samoin kuin metodin Date.now() antama kokonaisluku - millisekunteina lähtien ajankohdasta 1.1.1970 00:00:00 merkkijono - esimerkiksi "April 27, 2013 16:02:00 kolme kokonaislukua pilkulla toisistaan erotettuna: - esim. 2013, 04, 26 luo päiväyksen vuosi, kuukausi, päivä kuusi kokonaislukua pilkulla tosistaan eroteltuna: - 2013, 04, 26, 16, 02, 00, edellisen lisäksi määritellään myös tunnit, minuutit ja sekunnit
Jos parametreja ei anneta - new operaattorin avulla luotuun Date-olioon alustetaan automaattisesti olion luontihetken aika var luotu = new Date(2013, 04, 27, 16, 02, 00); var nyt = new Date(); // kutsuhetken aika
o Date oliolle määriteltyjä metodeja mm. getdate() palauttaa päiväyksen kuukauden päivän (1 31) getday() palauttaa päiväyksen viikonpäivän (0 6) getfullyear() palauttaa päiväyksen vuoden getminutes() palauttaa päiväyksen minuutit getmonth() palauttaa päiväyksen kuukauden (0 11) gettime palauttaa lukuarvon millisekunteina ajankohdasta 1.1.1970 parse() jäsentää merkkijonosta päiväyksen ja palauttaa lukuarvon millisekunteina tostring() muuntaa päiväyksen merkkijonoksi var nyt = new Date(); var paiva = nyt.getdate(); var kuukausi = nyt.getmonth(); var min = nyt.getminutes(); var sec = getseconds(); var nowinseconds = Date.now(); o Myös get metodeja vastaavat set metodit
o Math olioille on määriteltynä ominaisuuksia ja metodeita, jotka helpottavat matemaattisten operaatioiden tekemistä. esimerkiksi tallennettu piin (Π) arvo ominaisuudeksi Math.PI ja trigonometriset funktiot metodeiksi. o Math prototyypistä ei normaalisti ole tarvetta luoda oliota, vaan sen ominaisuuksia ja metodeita voi käyttää suoraan prototyypistä var pii = Math.PI; var rad = Math.sin(x); // x kokonaisluku, palauttaa arvon sin(x) radiaaneissa o Vakion π (PI) lisäksi oliolle on määriteltynä joukko muitakin matemaattisia vakioita Math-prototyypin ominaisuuksina E, LN2, LN10, LOG2E, LOG10E, SQRT1_2, SQRT2 o Matemaattisia metodit ovat: abs, sin, cos, tan, acos, asin, atan, atan2, ceil, exp, floor, log, max, min, pow, random, round, sqrt
o RegExp-oliot ovat säännöllisiä lausekkeita, joiden avulla on mahdollista tehdä hahmontunnistusta (pattern matching) merkkijonoille käsitellä merkkijonoja (etsiä ja korvata tunnistettuja osamerkkijonoja) o Ei käsitellä tässä tarkemmin, mutta esimerkiksi mjono = "33100 ; var okpostinro = new RegExp("^\d{5$ ); // tai var okpostinro = /^\d{4$/; if (document.lomake.postinro.value.search==-1) // ei ole käypä postinumero alert( Anna oikea postinumero ); o y.o. esimerkin säännössä käytetyt merkit sovitetaan merkkijonoon seuraavasti: ^ sopii merkkijonon alkuun \d sopii mihin tahansa numeromerkkiin {n sopii juuri n lukumäärään edeltävää merkkiä $ sopii merkkijonon loppuun
o for...in silmukan avulla käydään läpi olion kaikki ominaisuudet o silmukkamuuttuja saa vuorollaan arvokseen kunkin olion ominaisuuden nimen for (var mja in olio) { [lause;]* o voidaan laittaa käymään läpi myös taulukon alkiot var indeksit = "", arvot = ""; var omalista = new Array("Chinese", "English", "French"); omalista.uusikentta = "jotain"; for (var indeksi in omalista) { indeksit += indeksi + " "; arvot += omalista[indeksi] + " "; // indeksit sisältää "0 1 2 uusikentta" // arvot sisältää "Chinese English French jotain"
o for...in silmukan avulla käydään läpi olion kaikki ominaisuudet (esimerkki Olion ominaisuuksien läpikäynti ) <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>for..in -esimerkki</title> </head> <body> <h1>opetellaan JavaScriptiä - 6</h1> <p> Käydään läpi asiakastiedot ja muodostetaan niistä merkkijono. </p> <p> Tuloksena on: <span id= msg">ei tietoja.</span> </p> <script> var tieto; var str = ""; var asiakas={etunimi:"aarne", sukunimi:"asiakas",ika:30; for (tieto in asiakas) str+=asiakas[tieto]+" "; document.getelementbyid("msg").innerhtml = str; </script> </body> </html> getelementbyid("tunnus") - document olion metodi, noutaa elementin jonka id=="tunnus" innerhtml() DOM solmun ominaisuus, jäsentää merkkijonon ja korvaa solmun sisällön jäsennetyllä sisällöllä.
o Sekvenssi lauseita voidaan sulkea funktioksi lauseiden suoritus mistä tahansa kohdasta funktion kutsulla funktioon voidaan viedä kutsukohdasta arvoja parametrien avulla parametrit annetaan sulkeissa (sulkeet kirjoitetaan, vaikka parametreja ei olisikaan) <!DOCTYPE html> <html> <head> <meta charset="utf 8"> <title>asiakastietojen käsittely</title> <script type="text/javascript"> function Asiakas(p1, p2, p3) { this.etunimi = p1; this.sukunimi = p2; this.ika = p3; function muodostaasiakastiedot(tamaasiakas) { var tieto; var asiakastiedot = ""; for (tieto in tamaasiakas) asiakastiedot = asiakastiedot + tamaasiakas[tieto] + " "; return asiakastiedot; </script> </head> <body> <h1>opetellaan JavaScriptiä - 7 </h1> <p> Käydään läpi asiakastiedot ja muodostetaan niistä merkkijono. </p> <p> Tuloksena on: <span id= msg">ei tietoja.</span> </p> <script type="text/javascript"> var asiakas1 = new Asiakas("Kalle", "Kuluttaja", 28); var str1 = muodostaasiakastiedot(asiakas1); document.getelementbyid("msg").innerhtml=str1; </script> </body> </html>
o Funktiossa esitelty muuttuja on paikallinen funktiolle var a=1; var b=2; var c=3; function f1() { var a=11; b=22; function f2(){ var b=222; c=333; alert("f2-a,b,c: "+a+", "+b+", "+c); f2(); alert("f1-a,b,c: "+a+", "+b+", "+c); f1(); alert("globaali-a,b,c: "+a+", "+b+", "+c); o Lohkossa esitellyt muuttujat näkyvät sisemmille hierarkiatasoille (funktioihin) o Jos muuttujaa ei ole esitelty lainkaan, siitä tulee automaattisesti globaali
var luku, tulos; //globaaleja muuttujia function square(n) { var b = n * n; // b, n lokaaleja muuttujia return b; // palauta n * n; luku = 6; tulos = 2*square(luku); n funktion muodollinen parametri luku funktiolle välitetty, todellinen parametri Jos return-lausetta ei ole käytetty, palautettu arvo on undefined
o Funktion palauttamaa arvoa voi käyttää lausekkeessa function iseven(n) { return (n%2 ==0); // palauttaa boolean arvon var arvo = 6; if (iseven(val)) { // tee jotain o Jos if-lauseen ehtolausekkeen arvo on määrittelemätön, tulkki lähettää virheen (throws an error) o try catch -lauseella voidaan ottaa kiinni virheisiin
o Funktiolle välitettyjen parametrien lukumäärä ja tyyppi voi vaihdella eri kutsukerroilla o Paikallinen muuttuja (taulukko) "arguments automaattisesti käytettävissä kaikissa funktioissa o Parametreihin pääsee käsiksi sekä muodollisten parametrien, että arguments-taulukon kautta add(1, 2, 3); // palauttaisi 6 add(1, 2, 3, 4, 5); // palauttaisi 15 o Miten näin toimiva funktio toteutettaisiin? function add () { var s = 0; for (var i = 0; i < arguments.length; i++) s += arguments[i]; return s; add(1, 2, 3, 4, 5); // palauttaisi 15 add(1, 2, "3", 4, 5); // entä tämä?
o Funktio voi palauttaa eri tyyppisiä arvoja eri kutsukerroilla function teejotain (p1) { if (typeof(p1) == "number") return 0; // palauttaa luvun else if (typeof(p1) == "string") return nolla"; // palauttaa merkkijonon teejotain(1); // palautuu 0 teejotain("abc"); // palautuu "nolla" teejotain(); // palautuu undefined
o Voidaan luoda funktio ja antaa se arvoksi muuttujalle o Se voidaan edelleen antaa arvoksi toiselle muuttujalle var tieto, vastaus; tieto = function (a,b) { return a + b; var tieto2 = tieto; vastaus = tieto2(10,2);
o Koska funktio on vain tietoa, se voidaan välittää toiselle funktiolle parametrina function summaa(a,b){ return a() + b(); function yy(){ return 1; function kaa(){ return 2; answer = summaa(yy, kaa);
o Kun funktio fa välitetään toiselle funktiolle fb parametrina, ja fb suoritta funktion fa, kutsutaan fa:ta callback -funktioksi o Tämä antaa mahdollisuuden käyttää toisten kirjoittamia funktioita, jotka toteuttavat heidän määrittelemänsä toiminnan o Tätä käytetään tapahtumankäsittelijöiden toteutuksessa