Toon posts:

[js oo] inheritance simuleren

Pagina: 1
Acties:

Verwijderd

Topicstarter
ik weet niet of dit al wijd bekend is, maar ik heb het zojuist uitgevonden en daarbij had ik weing hulp van GoT topics, dus er is zeker weinig of nooit over gesproken hier.

Het gaat dus over het simuleren van inheritance in js. De meesten van jullie weten wel hoe je hele classes kan overnemen van een al bestaande class, namelijk door het prototype ervan over te schrijven:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
function beest(kleur) {
  this.kleur = kleur;
}
beest.prototype.vertel = function() {
  alert(this.kleur);
}

// nieuw child object
function hond(kleur,ras) {
  this.kleur = kleur;
  this.ras = ras;
}
hond.prototype = new beest();


nu heeft dus het object hond ook de method vertel. Je ziet al dat je in d constructor van het hondobject bezig bent met dezelfde properties toewijzen als in beest. Dat kan handiger, nl met de apply method:
JavaScript:
1
2
3
4
function hond(kleur,ras) {
  this.ras = ras;
  beest.apply(this,arguments);
}


dit is geloof ik allemaal wel ongeveer bekend, het staat ook vrij uitgebreid bescheven in de js oo tut van clay: http://www.xs4all.nl/~peterned/got/oojstuto.html

stel nu dat je voor het object hond de method vertel wilt uitbreiden, je kan dan gewoon de hele functie herdefinieren, maar als die erg veel lijkt op de method van beest is dat een beetje onzin. in bijvoorbeeld een programmeertaal als delphi kan je gewoon de hele method terugroepen met inherit. Naar iets dergelijks was ik ook op zoek binnen js.
JavaScript:
1
2
3
4
hond.prototype.vertel = function() {
  beest.prototype.vertel.apply(this, arguments);
  alert(this.ras);
}


doet het 'm

wat de apply method (van een functie) eigenlijk doet is die functie aanroepen binnen de context van het eerste argument van apply. dit is het object waarnaar elke this in de originele functie naar verwijst. het tweede argument is een array van vars die doorgegeven wordt aan die functie.

  • Clay
  • Registratie: Oktober 1999
  • Laatst online: 22-06 13:51

Clay

cookie erbij?

Klopt, je ziet het idd niet veel, en ueberhaupt is het gebruik van apply niet echt bekend. Ik heb een uitgebreidere versie van die tuto liggen (die ik nog steeds ff af moet maken :{ ) waar ik het volgende stukkie code toelicht;

JavaScript:
1
2
3
4
5
6
7
8
Function.prototype.extendsFrom = function(Super) {
    var self = this, func = function() {
        Super.apply(this, arguments);
        self.apply(this, arguments);
    }
    func.prototype = new Super();
    return func;
}


Hiermee kan je bv het genoemde Beest definieren, en dan Hond er zo van laten inheriten:

code:
1
2
3
4
5
function Hond() {
    // constructor
}

Hond = Hond.extendsFrom(Beest);


Die extends zorgt er voor dat de super met een apply in de constructor wordt aangeroepen (ala TS omschrijving) en zet de prototype naar een instantie van die Super.
Het enige nadeel is dat die een nieuwe uitvoerbare functie terug moet geven om de constructor te kunnen aanpassen (daarom wordt "self" ook geapplied). Ik weet ook eigenlijk niet of het ueberhaupt wel mogelijk is zonder return een functie inhoudelijk te veranderen, want dan zou het Hond = stuk er nog afkunnen.

Verder werkt het super :) heb het in Rotatrix ook gebruikt.

[edit]

Apply wordt trouwens niet ondersteund in IE5.0 en nog wat iets oudere meuk. Ooit in een helder moment heb ik daar deze fix voor geschreven:

JavaScript:
1
2
3
4
5
6
7
8
if(!Function.apply) 
Function.prototype.apply = function(obj, args) {
    var sArg = [], l = args.length;
    for(var i=0; i<l; i++) { sArg[i] = 'arg['+i+']'; }
    var action = new Function('obj','f','arg',
        'obj.$apply = f; obj.$apply(' + sArg.join(',') + ')');
    return action(obj, this, args);
}


Maar ik snap nu zelf eigenlijk amper meer hoe die werkt ;)

[ Voor 22% gewijzigd door Clay op 11-11-2003 13:28 ]

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


  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 13:41

GrimaceODespair

eens een tettenman, altijd ...

Het doorsluizen van die arguments lijkt me soms onhandig, omdat dan je hond precies dezelfde signature voor zijn constructor moet hebben als elk ander beest. Zelf roep ik in AS (maar ik weet niet zeker hoe dat in JS zit) altijd in mijn subclass gewoon super(a, b, ... ) aan.

Het kan natuurlijk een bron zijn van domme fouten, maar ik heb meestal andere constructors voor sub- en parentclasses waardoor ik gebruik moet maken van super(a, b, ...).

Wij onderbreken deze thread voor reclame:
http://kalders.be


Verwijderd

Topicstarter
als je in de problemen komt met je argumenten kan je ook call() gebruiken, die doet het zodner array, met alle argumenten los.

dus in hond: Beest.call(this,kleur);

dan heb je wat beter overzicht van wat je doet

  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 13:41

GrimaceODespair

eens een tettenman, altijd ...

Verwijderd schreef op 11 november 2003 @ 14:07:
als je in de problemen komt met je argumenten kan je ook call() gebruiken, die doet het zodner array, met alle argumenten los.
Ik denk dat je het concept van die apply dan niet helemaal begrijpt. Het gaat er net om dat je niet weet hoeveel argumenten er zijn.

Wij onderbreken deze thread voor reclame:
http://kalders.be


Verwijderd

Topicstarter
concept van apply (en call) is dat je een functie aanroept binnen de context van een andere functie, als je niet weet hoeveel argumenten je hebt gebruik je apply, anders lijkt het mij overzichtelijker om een call te doen.

Als je weet dat beest 1 argument heeft, dan hoef je alleen die ene door te geven. De constructor signatures hoeven helemaal niet hetzelfde te zijn in dat geval.

Overigens kan je ook met wat slim scripten wel op een gecontroleerde manier een onbekend aantal argumenten doorgeven door ze bijvoorbeeld in een array te pakken.

bijvoorbeeld voor een tabfield dat ik ooit maakte. dat ging eerst zo:
JavaScript:
1
myTab = new Tab('tab1','tab2','tab3');


die strings zijn dus de labels van een (onbekend) aantal tabs. Die geef ik nu als volgt door:
JavaScript:
1
myTab = new Tab(['tab1','tab2','tab3'],w,h);


omdat er die breedte en hoogte bijmoest (en nog wat muk), dan heb je dus altijd 3 argumenten, ongeacht hoe veel tabs je hebt.

offtopic:
waar blijft die js hilighter? is toch bijna dezelfde als die van php bv

[ Voor 20% gewijzigd door Verwijderd op 11-11-2003 14:21 ]


  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 13:41

GrimaceODespair

eens een tettenman, altijd ...

Euhm... laatste reactie, dan zwijg ik erover, want het gaat nergens over :)

Call kan jou misschien overzichtelijker aandoen, maar het gaat er net om dat, binnen een generieke opzet, je nooit kan weten over hoeveel argumenten dat het zal gaan. Dus als je een generieke aanroep hebt naar een super-class, kan je niet om apply heen.

Wij onderbreken deze thread voor reclame:
http://kalders.be


  • Clay
  • Registratie: Oktober 1999
  • Laatst online: 22-06 13:51

Clay

cookie erbij?

Daar sluit ik me bij aan :)

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


Verwijderd

Topicstarter
ik ook, want nu begrijp ik wat je bedoelt ;)

doel van dit topic was trouwens de community laten delen met dit gegeven, want het is volgens mij niet zo bekend. Een discussie over het al of niet overzichtelijk zijn van call of apply gaat idd nergens over.
Pagina: 1