Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: JS ja olio-ohjelmointi

Paulus M [16.09.2009 23:18:58]

#

Aiemmin juttelin olion ohjelmointii liittyvästä prototype määritteestä ja ei tullut ihan selkeäksi, niin täytyy vielä kysäistä vielä asiasta.

Eli viimeksi mua neuvottiin (https://www.ohjelmointiputka.net/keskustelu/19198-js-x-y-is-not-a-function) käyttämään prototyyppi määritettä luomaan olioita.

Jos tämä prototyyppi määrite kannattaa laittaa tai pitää laitta, minkä takia Javascriptin koodioppaassa ei neuvota sillain:

Koodioppaan neuvot:

function Henkilo(etunimi, sukunimi, ika)
{
    // Sijoitetaan parametreina tulevat tiedot olion omiin muuttujiin:
    this.etunimi = etunimi;
    this.sukunimi = sukunimi;
    this.ika = ika;
}

var Heikki = new Henkilo("Heikki", "Huttunen", 34);
var Saija = new Henkilo("Saija", "Sopanen", 18);

Ja valmista, meillä on kaksi oliota, jonka parametrejä voidaan muutta yksilöllisesti. Eli jos Saijan sukunimeä muutetaan, niin Heikin sukunimi ei muutu.


tässä on kuitenkin koodi, jota minulle on neuvottu käyttämään, eli pitäisi käyttää jotain prototype rakennetta. Miksi:

function Ani() {
    this.animaatiot = [];
}

Ani.prototype.uusi = function (nimi, lkm) {
    var i = this.animaatiot.length;
    this.animaatiot[i] = [];
    for (var j = 0; j < lkm; ++j) {
        this.animaatiot[i][j] = nimi + j;
    }
}


......


var ani = new Ani()

Eli tässä esimerkissä täytyy sotkea yksi ylimääräinen funktio, vai eikö tuota kamaa, joka on Ani.prototype.uusi:ssa, voisi viedä suoraan konstruktoriin taikka sitten vaan käyttää tuota "uusi" funkiota ihan niin kuin kaikkia muita olioiden jäsenfunktiota, niin kuin Javascript oppaasta on määritelty. Jaksaisko joku selittää, että minkä takia pitää olla tämä prototype vaikeuttamassa ihan perus olion luontia?

Metabolix [16.09.2009 23:45:08]

#

var a = new Ani();
a.funktio();

Nyt katsotaan, onko oliolla a jäsentä nimeltä funktio, ja jos on, yritetään kutsua sitä. Jos taas ei ole, katsotaan, sisältääkö a.prototype sellaisen.

Jos funktio lisätään muodostimessa, joka olio saa oman kopion siitä:

function Ani() {
  // Luodaan uusi kopio funktiosta.
  this.f = function() {
    alert("moi");
  }
}
var a = new Ani();
var b = new Ani();
alert(a.f == b.f); // false; molemmilla on oma kopio funktiosta!

Prototyypin kanssa funktioita on vain yksi. Hyötynä on, että säästyy muistia ja myös aikaa, kun joka kerta ei luoda uutta funktiota.

function Ani() {
  // this.prototype = Ani.prototype; Tämä tapahtuu automaattisesti.
}
// Luodaan vain yksi funktio.
Ani.prototype.f = function() {
  alert("moi");
}
var a = new Ani();
var b = new Ani();
alert(a.f == b.f); // true; a.prototype == b.prototype == Ani.prototype, funktiokin on siis sama.

Kannattaa muistaa, että JavaScriptissa ei ole luokkia; jokainen objekti on vain objekti, ja kaikki muu tapahtuu tämän prototyyppihomman avulla.

Paulus M [16.09.2009 23:58:19]

#

Ok, kiitti Metabolix, hyvin selkeästi opetat mistä on kysymys.

Eli siis protype komento on sitä varten, että jos jotain jäsenmuuttajaa tai jäsentä ei ole olemassa, se luodaan, mutta jos on, niin viitataan vain jo olemassa olevaan muuttujaan?

Eli periaatteesssa komento

Ani.prototype.muuttuja = 5 // on salittu.

document.write(a.muuttuja); // tulostaa 5?
a.muuttuja = 3;
document.write(b.muuttuja); // tulostaa 3?

Mutta tätä prototype hommaa ei tartte, jos haluaa tehdä kaikille omat funktiot ja jäsenmuuttujat? Tämä jäsenmuuttuja juttu voi olla kyllä aika tarpeeton, mutta laiton sen koska se on yksinkertaisempi yksikkö...


EDIT:

voiko vielä nopeasti kysäistä tälläisen kysymyksen:

if(ylhaalla)document.images[5].src = "kuvat/yhteysV.png";

miten vastaava kuvan vaihto tapahtuisi, jos haluaisin vaihtoo kuvaa kuvan id:n perusteella, tässä vaihdetaan kuvaa numero 5.

Eli tyyliin:

document.images.getById("KuvaPlaaPlaa").src = ....

Metabolix [17.09.2009 00:35:54]

#

Nyrkkisääntönä voisi pitää, että prototype sisältää asioita, jotka eivät muutu, eli funktioita ja esimerkiksi "luokkakohtaisia" vakioita. Esittämäsi koodin toimintaa voit testata itse. Tulosta a:n ja b:n muuttuja sekä ennen että jälkeen muutoksen, sillähän se selviää.

Jälkimmäiseen: document.getElementById("kuvan_id").src. Pääsääntöisesti kaikki elementit toimivat JS:n kannalta samalla tavalla. Historiallisista syistä joillekin (framet, formit, kuvat) on noita ylimääräisiä taulukoita kuten document.images. Itse suosittelisin, ettet käytä niitä ainakaan kuvien tapauksessa ollenkaan.

Paulus M [17.09.2009 01:06:30]

#

kiitti Metabolix! Jätkä on auttanut meikää kyllä monesti, siitä on ollut paljon apua. Fiksu kaveri oot, ei voi muuta sanoa.

jlaire [19.09.2009 18:13:27]

#

Paulus M kirjoitti:

Jos tämä prototyyppi määrite kannattaa laittaa tai pitää laitta, minkä takia Javascriptin koodioppaassa ei neuvota sillain:

Putkan JS-opas ei opeta kaikkia asioita ihan parhaalla mahdollisella tavalla. Jos osaa vähänkään englantia, kannattaa googlailla ja selata muitakin oppaita ja itse ECMAScript-standardiakin.

Yksinkertainen prototype-esimerkki, joka saatta vähän valaista asiaa:

Array.prototype.sum =
function () {
    var sum = 0;
    for (var i = 0; i < this.length; ++i) {
        sum += this[i];
    }
    return sum;
};

var array = [3,1,4,1,5,9];
alert(array.sum());
// 23

Perustyyppien (Array, Function, String jne.) prototyyppeihin voi ihan vapaasti lisätä omia metodeja ja ominaisuuksia. Monet JS-kirjastot laajentavat kieltä ja helpottavat sillä ohjelmointia juuri tällä tavalla.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta