Avatar billede lone_a_p Praktikant
13. november 2011 - 19:10 Der er 9 kommentarer og
1 løsning

OOP - lister?

Kære eksperter,

Jeg er ved at sætte mig ind i at benytte js på en objekt orienteret måde.

Jeg har fået følgende eksempel i et andet spørgsmål her på eksperten, men jeg forstår det ikke:

function AppClass() {
    this.idList = {};
    this.dateList = {};
}

var p = AppClass.prototype;
p.create = function(sType) {
    var a = arguments;
    var o = new this[sType](a[1], a[2], a[3], a[4], a[5]);
    this.idList[a[1]] = o;
    this.dateList[a[2]] = o;
    return o;
};

Hvad betyder {} ? Skal det forstås som et array? Altså hvis jeg putter det samme objekt i idList og dateList fylder koden så dobbelt eller er det netop fordelen ... altså at disse blot indeholder referencer til objekterne som man putter i "listerne".

Jeg har forsøgt at søge efter dette "{}" og javascript på nettet, men jeg kan intet finde om det. Vil du give mig et par søgeord til, hvad jeg overhovedet skal søge på, for at finde ud af, hvad det er?

Kunne der lige så godt have stået dette?:
this.idList = new Array();
this.dateList = new Array();

Mvh Lone
Avatar billede olebole Juniormester
13. november 2011 - 21:37 #1
<ole>

Undskyld, at jeg overså dine kommentarer/spørgsmål i den anden tråd  =)

Et array er altid talindekseret i JS. Associative arrays, som de kendes fra f.eks. PHP, findes ikke i JS. Et tomt JS-array kan oprettes på to måder:

var arr = new Array();
// - eller:
var arr = [];

Elementer i et JS-array tilgås altid med square brackets:

var str = arr[3];
// - eller:
arr[12] = "Tolv";

Et JS-object er strengindekseret - og minder mere om PHPs associative array. Et tomt JS-object kan oprettes på flere måder:

var o = new Object();
// - eller:
var o = {};
// - eller:
function MyObj(){};
var o = new MyObj();

Elementer i et JS-object tilgås med 'dot notation' eller square brackets:

var str = o.noget;
// - eller:
var str = o["noget"];
// - eller:
o.noget = "andet";
// - eller:
o["noget"] = "andet";

En lidt bedaget guide om JS-arrays og -objects.

developer.mozilla.org svarer ikke ligenu, men der kan du også læse om arrays og objects, hvis du går ind fra JS-referencens hovedside, jeg linkede til forleden.

- to be cotinued ...  =)

/mvh
</bole>
Avatar billede olebole Juniormester
13. november 2011 - 21:39 #2
PS: Et object har ikke en length property, som det kendes fra et array
Avatar billede olebole Juniormester
13. november 2011 - 22:28 #3
Hvad angår dit spm. om hvordan de gemmes. Jeg har lavet et lille eksempel og testet lidt på det. Først to objekter til storage og en objekt constructor:

var oList_A = {};
var oList_B = {};

function MyObj(nInx, nSome) {
    this.id = "ID:"+nInx;
    this.propSome = "Some:"+nSome;
    this.propTxt1 = "Bacon ipsum dolor sit amet pork belly sausage leberkäse, capicola tongue hamburger biltong."
                  + "Pastrami pork loin frankfurter prosciutto fatback beef ribs, filet mignon pork chop t-bone.";
    this.propTxt2 = "Bacon ipsum dolor sit amet pork belly sausage leberkäse, capicola tongue hamburger biltong."
                  + "Pastrami pork loin frankfurter prosciutto fatback beef ribs, filet mignon pork chop t-bone.";
    this.propTxt3 = "Bacon ipsum dolor sit amet pork belly sausage leberkäse, capicola tongue hamburger biltong."
                    + "Pastrami pork loin frankfurter prosciutto fatback beef ribs, filet mignon pork chop t-bone.";
}

Hvis jeg instantierer 100.000 objekter og gemmer dem i den ene liste, så æder min IE9 ca. 89.500KB RAM:

function foo() {
    var o;
    for (var i=0,j=200; i<100000; i++,j++) {
        o = new MyObj(i, j);
        oList_A["key"+i] = o;
    }
}

Gemmer jeg objektet i begge lister, æder den 114.500KB:

function foo() {
    var o;
    for (var i=0,j=200; i<100000; i++,j++) {
        o = new MyObj(i, j);
        oList_A["key"+i] = o;
        oList_B["key"+j] = o;
    }
}

Men hvis jeg nøjes med i B-listen at gemme indeksstrengen fra liste-A, æder den 131.500KB:

function foo() {
    var o;
    for (var i=0,j=200; i<100000; i++,j++) {
        o = new MyObj(i, j);
        oList_A["key"+i] = o;
        oList_B["key"+j] = "key"+i;
    }
}

Forklaringen er, at de refererer til samme dataobjekt. Du kan f.eks. prøve dette eksempel:

function foo() {
    var o;
    for (var i=0,j=200; i<100000; i++,j++) {
        o = new MyObj(i, j);
        oList_A["key"+i] = o;
        oList_B["key"+j] = o;
    }
   
    alert("Før vi sletter fra liste A: "+oList_B["key200"].propSome);
    oList_A["key0"].propSome = null;
    alert("Efter vi har slettet fra liste A: "+oList_B["key200"].propSome);
}

Men pas på! Hvis du sletter et helt objekt fra den ene liste, kan det stadig findes i det andet. Objektet ligger stadig i hukommelsen, men referencen i den ene liste er slettet.

Når et objekt ikke længere skal bruges, bør det derfor tømmes for properties, hvorefter referencerne til objektet bør slettes. Det bør frigøre hukommelse - med mindre, man får skabt cirkulære refrencer. Det er desværre ikke altid helt ukompliceret at styre memory leaks  :o|
Avatar billede olebole Juniormester
13. november 2011 - 22:42 #4
PS: Du bør på window.onbeforeunload rense applikationen som nævnt ovenfor. Alle objekt instanser, du laver skal 'dræbes'. Ellers frigøres hukommelsen ikke eller kun delvist ved sideskift. Ofte udstyres objekter derfor med en dispose metode, som tømmer objektet. Den kaldes - og objektet null'es.

Specielt IE har historisk været rigtig dårlig (læs:katastrofal!) til garbage collection, men den er blevet væsentligt bedre de seneste par versioner. Du kan dog, hvis du får alvorlige problemer med IE, kalde dens garbage collection manuelt:

if (window.collectGarbage) window.collectGarbage();

- men gør det kun, hvis det bliver nødvendigt. Det er en lidt tung affære. Gør det dog meget gerne til allersidst ved onbeforeunload.
Avatar billede olebole Juniormester
13. november 2011 - 23:11 #5
Nu, vi er i gang med dette 'essay', kan jeg lige vise et lille, sjovt eksempel på, at stort set alt i JS grundlæggende består af et objekt:

var a = new Array();
a["foo"] = "Dette ligner ";
a["bar"] = "et associativt ";
a["baz"] = "array ... ikk'?";

alert( a["foo"]+a["bar"]+a["baz"] );

var d = new Date();
d["foo"] = "Men det er ";
d["bar"] = "det ikke, nej!";

alert( d["foo"]+d["bar"] );

Det skyldes som sagt, at Array er et objekt, som arver fra Object, men er udstyret med særlige properties og metoder. Det er altså selve Array objektet, du sætter properties på. Dette gælder ikke kun Array, men også Date, String og alle de andre. Det kan dog af mange grunde ikke anbefales. Brug et objekt i stedet.
Avatar billede olebole Juniormester
13. november 2011 - 23:28 #6
Til sidst endnu et lille kuriosum: Enhver JavaScripter vil fægte med livet som indsats for påstanden, at JS-arrays er altid talindekserede. Sådan er det bare - det ved enhver - BASTA!

Prøv i sådan et selskab at påstå, at JS-arrays i virkeligheden altid er strengindekserede. Men prøv så lige at se her:

var a = new Array("en", "to", "tre", "fire", "fem");
alert( a["2"] );

"Jaja, olebole ... det er bare JS-fortolkeren, der er venlig."

Faktisk ikke! Prøv denne her:

var a = new Array("en", "to", "tre", "fire", "fem");
var i = 0;
for (var x in a) {
    alert("a[" +i+ "]: "+ a[x] +"\n("+ i +" == "+ x +") => "+ (i==x) +"\n("+ i +" === "+ x +") => "+ (i===x) +"\n(typeof "+ x +") => "+ (typeof x));
    i++;
}

Dette viser, der ligger et objekt nedenunder - og et tal i de square brackets oversættes til strengform, inden indekset anvendes mod det underliggende objekt.

Jaja, så er der til gengæld andre, der kender navnet på hver en tovende i den stående og løbende rig på et 5-mastet barkskib - eller ved, at det var Herberth Leopold Maximillian van der Schwandvogel III, som første gang brugte bæverfilt til en herrehat ... eller er på fornavn med alle sine kalorier. Nerds Unite!  *D
Avatar billede olebole Juniormester
13. november 2011 - 23:35 #7
Må jeg i øvrigt anbefale denne mumletekstgenerator efter alternativt koncept  0:)
Avatar billede lone_a_p Praktikant
14. november 2011 - 16:57 #8
Hej ole,

Tak for dit essay :)

Så jeg skal egentlig "bare" forstå listen som et nyt objekt med en slags properties og ingen metoder?

Jeg var også ude i at ville gemme et id-"array" og dato-"array". Så kan jeg oprette nye objekter som f.eks. var day20111114 = new Day(), som indeholder en række objekter Intake. Men i så fald bliver det vist objekterne som jeg putter i og ikke blot referencer? (men der er flere end de spiste ting, som skal knyttes til en dag, så det skal vel være et new Day()).

Jeg bliver vel nødt til at kunne kalde de enkelte dage, måltider, varer osv. for sig selv - altså ligesom vare["32"]. Hvordan får jeg ellers fat i en vare i OOP? Hvis en bruger klikker på "slet vare 32" på skærmen, så bliver jeg jo nødt til på en eller anden måde, at få fat i denne vare - og her tænker jeg vare["32"]. Ellers skal det være:
var vare32.delete();
I Array() er det jo rigtig nemt at få fat i det man skal bruge, det kan jeg ikke helt se hos OOP-delen.
Hvilke af ovenstående er korrekt, jeg har ikke rigtig set nogle eksempler på, hvor man knytter brugerevents sammen med OOP-koden.

Er du evt. kommet til at lave en tastefejl i følgende?:
"Men hvis jeg nøjes med i B-listen at gemme indeksstrengen fra liste-A, æder den 131.500KB:"
(jeg synes din tekst lyder som om tallet burde være mindre end hvis man gemmer objektet i begge lister - men tallet er større?)

Det er lige før jeg hopper tilbage til min gamle kodeform, for jeg er ikke sikker på, at jeg laver det rigtigt alligevel - og hvis jeg alligevel laver det om til noget "andet bøvlet", så er der jo ikke rigtig nogen pointe i det.
Er der evt. nogle kurser der kører i JS-OOP? Jeg søger både på tekst- og videotutorials, men det er som om at det hele er et forsimplet trin, som jeg har været igennem. Og jeg skal bruge den avancerede udgave :/ Eller nogen som man kan købe sig til at få hjælp hos. Det værste er, at jeg ikke engang helt ved, om der er nogen gevinst ved det, for det jeg har lavet virker jo.
Avatar billede olebole Juniormester
15. november 2011 - 23:46 #9
Listen skal du ikke "bare" forstå som et objekt. Den er skoleeksemplet på et JavaScript objekt  =)

Jeg lavede ikke en tastefejl. Jeg skrev det for at vise, at selv en lillebitte streng fylder mere end, når jeg gemmer objektet anden gang. Altså er der (anden gang) tale om at gemme en reference til objektet - ikke objektet selv.

Den bøvlede løsning er at bruge arrays, men ofte den letteste at overskue for 'begynderen'. Med tiden vil du finde ud af, at OOP ikke er til at komme udenom. jQuery ville således være en komplet uoverskuelig og uhåndterlig kæmpeklump af koder, hvis det ikke var skrevet OO - og det gælder stort set en hvilken somhelst kode, der gemmer sig på din PC.

Hvordan du skal organisere koden, kommer an på, hvordan din app præcist er opbygget/skal virke. Det har jeg stadig ikke sat mig grundigt ind i. Umiddelbart lyder det dog, som om du burde bruge PC/tablet/smartphone som et enkelt, lille interface - og lade logikken ligge på serveren. Datatrafikken kan gøres ganske lille og kan foregå via Ajax. Det er jeg helt sikker på, vil gøre det lettere for dig selv og hurtigere for brugerne.

Jeg kender ikke steder på nettet, der forklarer OOP grundigt og seriøst fra bunden. Som oftest er der tale om diskusion af specifikke problematikker, forbundet med OO - rettet mod et erfarent publikum. Desværre  :o|
Avatar billede lone_a_p Praktikant
28. juni 2012 - 21:51 #10
lukket
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester