Javascript

2. viikko

Tekijät: Marko Haanranta, Kasper Kivikataja, Kati Kyllönen, Jussi Miestamo

Pääsivu
Tyyppiturvallisuuden tavoittelua 2. viikko
3. viikko
4. viikko

2. Hyviä ohjelmointikäytäntöjä:

2.1 Tyyppiturvallisuuden tavoittelua

Javascriptissä muuttujat ja parametrit ovat tyypittömiä, mutta niiden arvoilla on tyypit. Javascriptin tietotyypit ovat merkkijono (string), luku (number), totuusarvo (boolean), taulukko (array), objekti (object), olematon (null) ja määrittelemätön (undefined). Vaikka muuttujilla ei olekaan tyyppiä, on arvojen tyyppejä syytä tarkistaa, jotta ohjelmat eivät tuottaisi odottamattomia tuloksia. Erityisesti käyttäjän syötteitä on hyvä tarkastella virheiden varalta. Javascriptissä yhteenlasku voidaan suorittaa ongelmitta luvun ja String-tyypin olion välillä.

function sum(a,b){
    return (a+b)
}

write(sum(2,"w4"))                          //tulostaa "2w4"

Javascript tarjoaa - kuten tunnettua - funktiot parseInt() ja parseFloat() kokonais- tai liukulukujen eristämiseen syötteestä: jos syöte alkaa numerolla, siitä erotetaan numero-osa, ja loppu jätetään huomiotta. Joissain tapauksessa tämä on täysin riittävä tapa varmistaa se, että syöte on kelvollista. Jos ohjelmoija odottaa saavansa syötteenä esimerkiksi kokonaisluvun, vaaraa ei ole, koska parseInt() palauttaa aina kokonaisluvun tai tietotyypin undefined. Tietysti ohjelmakoodin pitää olla rakennettu niin, että undefined:iin on varauduttu, mutta käytettiin mitä tahansa keinoa tyyppien tarkastamiseen, undefined:iin on joka tapauksessa aina varauduttava, jotta ohjelman toiminta olisi ennakoitavaa.

Vaikka yllä oleva esimerkki on yksinkertainen, pelkkä undefined:iin varautuminen ei riitä. Koska oletettavaa on, että käyttäjä (tai funktiota kutsuva ohjelmoija) ei kirjoita syötteeseen lainausmerkkejä, esimerkin syötteen tekee kelvottomaksi todennäköisemmin käyttäjän lyöntivirhe:

write(sum(2,w4))                   //Tulostaa konsoliin ReferenceError: w4 is not defined;

Tällaisten tilanteiden varalta pitäisikin tarkistaa, onko syöte ylipäätään kokonaisluku. On onnekasta, jos syöte alkaa numeroilla, mutta jos ei ala, parseInt() ei pelasta.

Tyyppien tarkistus ohjelmakoodissa on erityisen tärkeää juuri käyttäjän syötettä käsiteltäessä, sekä muutoinkin ohjelman ulkoisissa rajapinnoissa.

2.2 Ehdotus kirjastofunktiosta tyyppitarkastusten tekemiseksi

Köyhän miehen esimerkki tyyppiturvallisuutta tavoittelevasta ohjelmointityylistä, viikon 1 kuusitehtävää mukaillen.

var korkeus = parseInt(prompt("Anna kolmion korkeus:"));

if (hasValue(korkeus) && isNumber(korkeus) 
    && korkeus > 0 && korkeus < 22){

    var alimman_leveys = 1 + ((korkeus-1)*2);
    var taman_leveys = 1;
    var tyhjia = (alimman_leveys-taman_leveys)/2;

  for (var i = 0 ; i < korkeus; i++){
    var tyhjat = new Array(tyhjia+1).join(" ");
    var tahdet = new Array(taman_leveys+1).join("*");

    write(tyhjat + tahdet);
    taman_leveys = taman_leveys +2;
    tyhjia = (alimman_leveys-taman_leveys)/2;
  }

}
else{
  alert("Ei käy");
}

2.3 Yleisen tason pohdiskelua tyyppiturvallisuuden tavoittelusta

Voidaan tietysti pohtia, kuuluuko dynaamisesti tyypitettyjen kielten luonteeseen lainkaan tyyppiturvallisuuden tavoittelu. Kuitenkin, jos tavoitellaan ennustettavasti toimivaa ohjelmaa on se mielestämme tarpeen. Tarjolla on kuitenkin useita keinoja varmistaa käyttäjältä tulevan syötteen oikeellisuus käyttämällä esimerkiksi javascript-ohjelmointikehysten tarjoamia lomakevalidaattoreita. Säännölliset lausekkeet ovat myös yleisesti käytetty, varsin tehokas tapa käyttäjän syötteiden tarkastamiseen.

2.4 Loppukevennys

Tätä tehtävää tehdessämme, löysimme kyseisen artikkelin MikroPC-lehdestä

Olli Vänskä, MikroPC, 5.8.2013, 9:25 Työntekijän nimi "Nolla" sotkee yrityksen koko henkilöhaun Mikään tietojärjestelmä ei ole täydellinen, mutta joskus ongelmia esiintyy varsin kummallisista syistä. Erään yrityksen työntekijähaku kaatui jatkuvasti sen takia, että sen palkkalistoilla on mies nimeltä Null (Nolla).

http://www.mpc.fi/kaikki_uutiset/article918607.ece

Lähteet:

http://www.w3schools.com/js/js_datatypes.asp

http://www.cs.helsinki.fi/u/wikla/OTjs/materiaalia/tyyppeja/

http://united-coders.com/matthias-reuter/handling-the-unexpected-type-safe-functions-in-javascript/