[JS] Alternatieven voor smerige javascript 'truukjes'

Pagina: 1
Acties:

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
Ik ben eens serieus bezig iets OO in Javascript te proggen en ik stuit nog op enkele problemen die ik gewoon niet netjes weet op te lossen. Het knaagt ontzettend aan me dus als iemand me kan bevrijden met een nette duidelijke methode dan ben ik je erg dankbaar :)

Het probleem is dat ik vanuit een object dynamisch elementen in het document aan het wijzigen en toevoegen ben en ik ze events toewijs waarin variabelen gebruikt worden die eigenlijk niet zo goed bereikbaar zijn vanuit het betreffende element.

Stel ik wil 10 plaatjes toevoegen die, van een member van het object dat ze aanmaakt, een functie aanroepen met een bepaald nummer (als index oid). Even een stukje voorbeeld code om duidelijk te maken wat ik bedoel:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function EenObject()
{
    this.eenAnderObject = new EenAnderObject();
    
    this.voegPlaatjesToe = function()
    {
        for ( i = 0; i < 10; i++ )
        {
            img = document.createElement("img");
            
            eenAnderObject = this.eenAnderObject;
            
            img.onmouseover = function ()
            {
                eenAnderObject.doeIets();
            };
            
            onclickEvent = null;
            evalCode = "onclickEvent = function(){";
            evalCode += "eenAnderObject.doeIetsOpBasisVanIndex(" + i + ");";
            evalCode += "}";
            eval(evalCode);
            
            img.onclick = onclickEvent;
            
            document.getElementById('eenElement').appendChild(img);
        }
    }
}

Een beetje zichzelf respecterend scripter is net bijna naar de wc gerent om de maaginhoud op een zeer onsmakelijke manier in de pot te leggen :P

Hier zitten 2 smerige truukjes in verwerkt. De eerste is "eenAnderObject = this.eenAnderObject;" wat ik doe om in het mouseover event van het plaatje een method te kunnen aanroepen van dat object. this verwijst namelijk op dat moment naar het plaatje zelf en niet naar de instantie van EenObject die het plaatje maakte. Het tweede smerige truukje is om de waarde van 'i' direct in een functie te kunnen gebruiken. Als ik deze namelijk direct gebruik, dan gebruiken alle plaatjes de laatste waarde van i, namelijk 9.

Het enige wat ik zou kunnen bedenken om dit op te lossen is om deze waardes toe te wijzen aan custom attributen van img. iets als img.eenAnderObject = this.eenAnderObject. Dit heb ik echter nog niet uitgeprobeerd omdat dit volgens mij niet mogelijk is. Ik ga het zo wel even uitproberen, maar ik ben toch benieuwd naar wat andere creatieve geesten hier van kunnen maken.

[ Voor 9% gewijzigd door Michali op 08-05-2005 13:18 ]

Noushka's Magnificent Dream | Unity


Verwijderd

/me mept Michali

Objecten in javascript geschreven door Clay. Hier moet je wel veel nuttige tips uit kunnen halen :)

  • coubertin119
  • Registratie: Augustus 2002
  • Laatst online: 29-04 17:12
Je zet memberfunctions in de object-declaratie zelf. Clay leert je in z'n schrijfsel dat zoiets niet goed is.

Dat andere probleem zal ik vanavond 's bekijken.

Skat! Skat! Skat!


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
Verwijderd schreef op zondag 08 mei 2005 @ 13:34:
/me mept Michali

Objecten in javascript geschreven door Clay. Hier moet je wel veel nuttige tips uit kunnen halen :)
Wat ik zelf al voorstelde blijkt dus te werken 8)7

De rewrite:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function EenObject()
{
    this.eenAnderObject = new EenAnderObject();
    
    this.voegPlaatjesToe = function()
    {
        for ( i = 0; i < 10; i++ )
        {
            img = document.createElement("img");
            img.eenAnderObject = this.eenAnderObject;
            
            img.onmouseover = function ()
            {
                this.eenAnderObject.doeIets();
            };
            
            img.index = i;
            
            img.onclick = function()
            {
                this.eenAnderObject.doeIetsOpBasisVanIndex(this.index);
            };
            
            document.getElementById('eenElement').appendChild(img);
        }
    }
}

Gaat perfect zo! Allemaal bedankt :+

Noushka's Magnificent Dream | Unity


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
coubertin119 schreef op zondag 08 mei 2005 @ 13:39:
Je zet memberfunctions in de object-declaratie zelf. Clay leert je in z'n schrijfsel dat zoiets niet goed is.

Dat andere probleem zal ik vanavond 's bekijken.
Clay zegt dat het niet fout is, maar gewoon wat langzamer. Persoonlijk zet ik het lekker bij elkaar zoals het nu is. En heb ik member variabelen en methodes die ze accessen gewoon bij elkaar. Dat vermindert variable en code span, wat bijdraagt aan leesbaardere, onderhoudbaardere en daardoor potentieel qualitatief beter code. Bovendien ben ik gewend zo te werken en ga ik het pas anders doen als ik echt een performance hit ergens merk. Wat voor nadelen zou je nog meer kunnen opnoemen dan?
edit:

typo's

[ Voor 3% gewijzigd door Michali op 08-05-2005 16:02 ]

Noushka's Magnificent Dream | Unity


  • André
  • Registratie: Maart 2002
  • Laatst online: 06-05 11:13

André

Analytics dude

De performance problemen merk je pas echt met real-time stuff zoals bijvoorbeeld js-animaties of games, in die gevallen kun je wel beter met prototyping werken :)

  • Clay
  • Registratie: Oktober 1999
  • Laatst online: 25-02 11:17

Clay

cookie erbij?

Michali
Ik ben eens serieus bezig iets OO in Javascript te proggen en ik stuit nog op enkele problemen die ik gewoon niet netjes weet op te lossen. Het knaagt ontzettend aan me ...

...

Persoonlijk zet ik het lekker bij elkaar zoals het nu is. En heb ik member variabelen en methodes die ze accessen gewoon bij elkaar. Dat vermindert variable en code span, wat bijdraagt aan leesbaardere, onderhoudbaardere en daardoor potentieel qualitatief beter code. Bovendien ben ik gewend zo te werken en ga ik het pas anders doen als ik echt een performance hit ergens merk. Wat voornadelen zou je nog meer kunnen opnoemen dan?
Als je serieus bezig bent met OO en het netjes wil doen omdat het anders aan je knaagt moet je object methodes dus prototypen ;) Op zich is er geen verschil in uitvoer van de code, echter als je prototypet horen de methodes al voordat er een instantie van bestaat bij je "class" (zoals het hoort). Als je ze inline toevoegt gebeurt dat voor elke instantie weer opnieuw, en hoort er in wezen nog helemaal niets bij je class.

Leesbaarheid en onderhoudbaarheid zijn identiek, Qualitatief is het inline imo zeker niet beter :P Het enige wat inline toevoegen je wel toestaat te doen - wat met prototypen niet kan - is een soort private variabelen in de scope van je constructor definieren, en in je member functies gebruiken, als een soort globale variabelen in je class. Soms handig, maar het maakt je code vaak niet leesbaarder.

Instagram | Flickr | "Let my music become battle cries" - Frédéric Chopin


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
Clay schreef op zondag 08 mei 2005 @ 16:02:
[...]


Als je serieus bezig bent met OO en het netjes wil doen omdat het anders aan je knaagt moet je object methodes dus prototypen ;) Op zich is er geen verschil in uitvoer van de code, echter als je prototypet horen de methodes al voordat er een instantie van bestaat bij je "class" (zoals het hoort). Als je ze inline toevoegt gebeurt dat voor elke instantie weer opnieuw, en hoort er in wezen nog helemaal niets bij je class.

Leesbaarheid en onderhoudbaarheid zijn identiek, Qualitatief is het inline imo zeker niet beter :P Het enige wat inline toevoegen je wel toestaat te doen - wat met prototypen niet kan - is een soort private variabelen in de scope van je constructor definieren, en in je member functies gebruiken, als een soort globale variabelen in je class. Soms handig, maar het maakt je code vaak niet leesbaarder.
Prototyping is maar een taalconstructie en heeft imo niet zo veel met OO te maken. Het gaat me meer om de princiepes. Het gebruik van eval() statements en lokale variabelen in andere functies gebruiken zoals ik in de start post deed vind ik dan wel weer smerig en dát knaagt aan me. Bovendien vind ik het fijn om member variabelen en methods die daar gebruik van maken bij elkaar te houden. Met prototyping wordt dit allemaal uit elkaar getrokken. Het is niet heel erg, maar maar ik vind het fijn zoals het nu werkt. Dit komt ook meer overeen met hoe ik werk in PHP5 en Java, dus als ik er echt problemen van ga merken stap ik wel over. Die problemen zie ik echter nu niet, dus waarom zou het dan anders gaan werken als het nu ook perfect gaat? Ik ben wel voor goede technieken, maar dan moeten de voordelen wel duidelijk zijn zodat ik het kan vergelijken met de andere mogelijkheden.

Maar nu weer ontopic :P

Noushka's Magnificent Dream | Unity

Pagina: 1