23. august 2006 - 01:38Der er
26 kommentarer og 2 løsninger
Påhæft method til property
Jeg har et simpelt objekt med nogle properties i: function foo() { this.foobar = 15; funtion multiply() { return this*2; } } Nu ønsker jeg at kalde min foo med flg.: myFoo = new foo(); var newfoobar = myFoo.foobar.multiply(); og få 30 retur
Jeg ved godt at nested innerfunction er private til outer og det er sikkert også derfor ovenstående ikke virker *S*
// initier objekt, tildel værdi og beregn var f = new foo(); f.foobar.value = 15; f.foobar.multiply();
Jeg kan ikke lige gennemskue om man kan lave en default-attribut på et javascript-objekt, men der kommer sikkert nogle kvalificerede bud fra andre brugere senere... :)
Jeg har begået mig en del i VB og COM, så deraf udtrykket. I COM taler man om default attributter/-funktioner som sådan nogle egenskaber der aktiveres på et objekt, hvis man ikke angiver en specifik attribut/funktion (det er lidt noget rod, men praktisk for den dovne programmør). Eksempelvis kan man typisk på et collection-objekt, kalde enten obj(1) eller obj.item(1) for at hente det første element i listen - her er item altså default-funkton på collection-objektet...
Mht. fleksibiliteten af funktionen, så er jeg da tilbøjelig til at være enig (men det lå bare ikke i "opgaven", så derfor tænkte jeg den ikke med i eksemplet). Den øgede fleksibilitet giver typisk også øget kompleksitet og det er sjældent godt, hvis man skal eksemplificere noget. Du er vel også selv tilhænger af KISS-princippet (synes jeg at erindre)...?
Der er ingen problemer i at angive default-værdier, og det gøres da også oftest i javascript-objekter ved at man i constructor-funktionen sætter sådan en værdi, evt. efter en test af parametre:
function myObject(parm1,parm2,parm3){ this.parm1 = parm1; this.parm2 = parm2 ? parm2 : 615; this.createDate = new Date(); }
Bemærk at jeg ikke taler om default-parametre til en funktion, men default-funktioner/-attributter på et objekt. Det er vist en COM-feature, som jeg ikke tror er særlig velset i et normalt objektorienteret miljø, så det er forståeligt, hvis det forekommer sært for nogen (jeg aner ikke om du selv har arbejdet med COM, så jeg vil ikke gøre nogle antagelser).
Jeg tror faktisk det vil svare til at definere en toString-funktion på et javascript-objekt, som returnerer værdien af value-attributten (det lader faktisk til at være løsningen :))...
var newfoobar = myFoo.foobar.multiply(); rettet til: var newfoobar = myFoo.multiply(myFoo["foobar"]);
... multiply er ikke en function på variablen foobar - men funktionen myFoo.multiply ønskes kørt på variablen myFoo.foobr som den nye variabel newfoobar så tildeles værdien af.
... og så overførsel af t værdien som beregningen skal ske på ...
...men anonyme funktioner har bare den ulempe, at de kommer til at ligge på alle forekomster af objektet foo (prototyper defineres kun et sted og koden ligger altså kun en gang i hukommelsen - ret mig hvis jeg tager fejl).
Hmmm, den del ved jeg ikke noget om - det ved Rønving bedst :) (er også selv nysgerrig efter om functionen bliver kopieret når det er en prototype - eller om der blot er en reference til funktionen)
Hej og tak for alle de svar, men jeg synes ikke rigtigt vi har ramt hovedet på sømmet. softspot -> i første omgang ser dit forslag korrekt ud, men så ser jeg at du meget simpelt bruger this.value * 2, og... det skal være mere fleksibelt end det.
Det jeg ønsker er... jeg hæfter lige lidt mere på min oprindelige:
function foo() { this.foobar = 15; this.widget = 45;
funtion multiply() { return this*2; } }
altså... så vil jeg gerne sige myFoo = new foo(); myFoo.foobar.multiply(); skal gerne give 30 og myFoo.widget.multiply(); skal gerne give 90
Jeg så på et tidspunkt noget med man laver en inner function med noget with(this)... ? ved I noget om det måske er vejen?
mclemens -> jeg er ikke interesseret i at kalde en metode med nogle argumenter... det kræver for meget indsigt og er ikke indkapslet nok ;-)
roenving-> du har nogle gode konsistente regler, dem er jeg glad for at lære *S* Tak..
Jeg kan ikke lige se en løsning på hvordan du skal få den til at fungere, hvis du vil være i stand til at tildele værdier til attributterne efter din constructor er kørt - faktisk kan jeg heller ikke lige gennemskue, hvordan du skal få den multiply-funktion til at køre på de attributter med simple numeriske typer (jeg har i det mindste ikke haft held med at definere funktionelle funktioner på foobar-attributten).
Jeg kan dog se en løsning som dog bliver lidt mere omstændig end den du umiddelbart er ude efter og den ser således ud:
function Num(value) { this.value = (!isNaN(value) ? value : 0); }
function foo() { this.foobar = new Num(0); this.widget = new Num(0); }
// initier objekt, tildel værdi og beregn var f = new foo(); f.foobar.value = 15; f.widget.value = 45; f.foobar.multiply(); f.widget.multiply();
Det er muligt du kan bruger det indbyggede Number-objekt og så definere en prototype-funktion på dette som hedder multiply, men det synes jeg heller ikke jeg havde succes med. Der er givetvis andre som er mere erfarne udi JS og kan give dig en forkromet løsning... det var mit umiddelbare bud.
Hov, nej min fejl - det er jo kun hvis værdien af widget eller foobar skal rettes (sad og alert'ede f.widget.value istedet for f.widget.multiply()) ... Undskyld - og igen FEDT!
((( tilføjet denne funktion: foo.prototype.add = function(e,v) { this[e]=new Num(v); /* den opretter en variabel på foo / f objectet efter contructoren er køre ... this[e] kan ikke skrives som this.e i dette tilfælde */ } )))
så kan den også kaldes uden den anden parameter, i hvilket tilfælde den så vil få standardværdien 0. Altså
f.add('widget');
Mht. aflæsning af variablerne, kan man definere en toString-funktion på Num-objektet (og måske endda en valueOf-funktion), som returnerer værdien af objektet, så slipper man for at kalde med f.widget.value, når variablen skal udskrives. Det kunne se således ud:
// metoden som kaldes, hvis objektet benyttes ifm. operationer der vedrører // aflæsning, f.eks. alert(obj) Num.prototype.toString = function() { return this.value; }
// metoden som kaldes, hvis objektet benyttes ifm. operationer på primitive typer, // så som addition, substraktion osv. // Vær opmærksom på at at valueOf også bliver kaldt i dette tilfælde: // alert("widget = " + obj); // da der er tale om en addition... Num.prototype.valueOf = function() { return this.value; }
og værdien kunne så aflæses således:
alert(f.widget);
i stedet for
alert(f.widget.value);
Den sidste version vil stadig fungere, men metoden uden eksplicit angivelse af value-attributten virker bare lidt mere naturlig. Man SKAL stadig benytte value-attributten ved tildeling. Altså som hidtil:
Jeg har ikke rigtig bidraget med andet end en lille funktion jeg lagde ind i softspot's (add) og så lidt "spam" i trådem - så det er nok en meget, meget, meget lille bid :o)
... (((synes at det var softspot's 23/08-2006 23:17:23, der fik det hele til at køre))) ...
Jamen, jeg takker for point - og hvis roenving også vil have en del af kagen må han jo lige sige til, så lægger jeg lige en lille kage... (hmmmm... der er et eller andet galt med den sætning...?? ;-)).
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.