OOP i JavaScript

Tags:    javascript
Skrevet af Bruger #4575 @ 18.08.2005

Oversigt


1. Hvad er OOP?
... 1.1. Hvorfor bruge OOP?
2. Hvordan bruger man OOP i JavaScript?
... 2.1. Variabler
... 2.2. Funktioner
...... 2.2.1. Prototype
...... 2.2.1. Manuel tilføjelse af funktioner
... 2.3. Prototype vs. manuel tilføjelse af funktioner
3. Afrunding

1. Hvad er OOP?


OOP står for objekt orienteret programmering, og dækker over brugen af klasser. Når man taler om klasser inden for programmering, er det egentligt en sammensætning af funktioner og variabler, som arbejder sammen med hinanden, for at løse diverse problemsætninger.
Man kunne f.eks. have behov for at lave et tabbed objekt til sin side - Her ville det være ideelt at lave en klasse, som indeholdt de funktioner samt variabler der var nødvendige for at lave det tabbede-objekt.

Hvis du i forvejen programmerer i C++, C# eller Delphi (ikke så udbredt i Delphi), så kender du formentligt allerede til principperne for OOP, men det er en smule anderledes at benytte OOP i js, men mere om dette senere!

1.1. Hvorfor bruge OOP?


Der er mange grunde til at benytte OOP, men som jeg ser det, så er de 2 væsentligtste fordele ved OOP

1. Du kan genbruge din kode - Lad os tænke videre over det tidligere eksempel med et tabbed objekt. Hvad nu hvis du skulle bruge 3 tabbede objekter på sammme side? - Så ville det være nok at kode klassen én gang, og blot oprette 3 objekter!
2. Det gør din kode mere overskuelig, hvis du skriver klasser, og gemmer disse i JavaScript-Libaries (mere om dette i næste artikel!).

Men lad os komme i gang med at få lavet nogle klasser!

2. Hvordan bruger man OOP i JavaScript?


I js starter man med at lave en constructor-funktion - Den funktion, som skal kaldes når klassen skal oprettes:

Fold kodeboks ind/udKode 


Når man opretter klasser, er det god skik at skrive constructor-funktionens navn med stort forbogstav, i modsætning til normale funktioner, som altid bør starte med små bogstaver.

Når så man har oprettet sin klasse, er det jo klart at man ønsker at kunne oprette et objekt, som indeholder klassens funktioner og variabler. Det gøres meget simpelt ved at benytte new operatoren:

Fold kodeboks ind/udKode 


Syntaksen for at oprette en klasse er:

Fold kodeboks ind/udKode 


Når nu du har oprettet en klasse, så er det jo væsentligt at vide hvordan du tilføjer variabler og funktioner til denne - Ellers ville der jo ikke være nogen idé i at benytte dem, så lad os fortsætte med hvordan du tilføjer variabler:

2.1. Variabler


Når du laver klasser vil du ofte have behov for at gemme informationer specifikt til denne klasse, men dette skal gøres lidt anderledes end normalt. Vi skal nu benytte this operatoren, som fortæller browseren at variablen skal vedhæftes specifikt til denne klasse:

Fold kodeboks ind/udKode 


Dette skulle gerne give en besked med indholdet test.

På denne måde kan du få variablerne til at "høre til" klassen, og hvis du vil have fat i dem i andre funktioner fra klassen skal du blot bruge
Fold kodeboks ind/udKode 


Vil du derimod have fat i variablen uden for klassen skal du bruge

Fold kodeboks ind/udKode 


Hvor klasse skal udskiftes med navnet på den variabel, som indeholder klassen.

Nu skulle du så gerne lære at tilføje nogle funktioner, så lad os komme lidt videre :)

2.2. Funktioner


For at tilføje en funktion til din klasse kan du benytte 2 metoder. Den første går ud på at nedarve funktionerne til klassen med prototype operatoren, og den anden går ud på manuelt at tilføje funktionerne i Constructor funktionen.

2.2.1. Prototype


For at tilføje en funktion til en klasse med prototype operatoren skal du selvfølgelig først oprette din klasse:

Fold kodeboks ind/udKode 


Derefter tilføjer du funktionerne til din klasse, ved at nedarve dem med prototype operatoren, lad os sige vi vil tilføje functionOne og functionTwo:

Fold kodeboks ind/udKode 


Som du kan se, så definerer vi funktionerne lidt anderledes end vi er vant til, da de først skal nedarves til klassen, og derefter defineres som funktioner.
Den generelle syntaks for at nedarve funktioner til en klasse med prototype operatoren er:

Fold kodeboks ind/udKode 


2.2.2. Manuel tilføjelse af funktioner


Når vi tilføjer funktionerne manuelt til en klasse, så opretter vi den som vi plejer, og tilføjer dem så i Constructor funktionen, lad os tage udgangspunkt i samme eksempel som før:

Fold kodeboks ind/udKode 


Som du kan se, så er det bare at oprette funktionerne som normalt, og så tilføje dem i constructoren lige som med variabler.
Det er som regel en god ide at starte funktioner, som tilføjes til en klasse, med klassens navn - På den måde undgår man kambulation med andre funktionsnavne.

2.3. Prototype vs. manuel tilføjelse af funktioner


Der er reelt set ikke nogen forskel på hvilken måde man benytter til at tilføje funktionerne til sin klasse - Det er et spørgsmål om hvilken måde man finder lettest at benytte.
Personligt foretrækker jeg prototype operatoren, da man på den måde får et bedre overblik over sin kode (Synes jeg!).

3. Afrunding


Hvornår skal du så benytte klasser? - Der er 2 tidspunkter det kan betale sig, at benytte klasser.
1) Hvis du skal bruge det samme stykke kode mange gange, lad os f.eks. sige, at du har lavet en klasse til at redigere et billede, og har behov for at gøre det flere steder, så kan du genbruge klassen.
2) Hvis du har en masse funktioner, som alle vedrører en bestemt ting på din side, kan det give et bedre overblik at samle det i en klasse.

Når du koder klasser, kan det ofte foretrækkes at gemme klassen i et eksternt JavaScript Libary, med endelsen .js, og så tilføje det på sin side med følgende kode:

Fold kodeboks ind/udKode 


I DinFil.js skal du så gemme følgende, med udgangspunkt i det tidligere eksempel:

Fold kodeboks ind/udKode 


Det var alt for denne gang, er du i tvivl, så spørg i forummet :)

Hvad synes du om denne artikel? Giv din mening til kende ved at stemme via pilene til venstre og/eller lægge en kommentar herunder.

Del også gerne artiklen med dine Facebook venner:  

Kommentarer (10)

User
Bruger #2730 @ 19.08.05 09:31
Det fattede jeg ikke! Specielt ikke det med constructoren. Kan ikke finde ud af hvad din klasse hedder, hvad der gør den til en klasse osv. Synes du blander begrebet constructor sammen med en klasse du kalder en constructor... Findes der specielle keywords der afgør om noget er en klasse eller ej? Hvis man har en constructor, har man så også en destructor, eller hvordan håndteres hukommelse allokering?
User
Bruger #4575 @ 20.08.05 17:07
1) Navnet på min klasse er jo i og for sig underordnet, men i eksemplerne har jeg valgt at bruge navnet Constructor (Burde måske have været Class)

2) Forskellen på, om noget er en klasse eller ej afgøres når funktionen klades:
Hvis man skriver var klasse = new FunktionsNavn(); Ja så er det en klasse, hvis man bare kalder funktionen, så er det bare en funktion.

3) Så vidt jeg ved, er det endnu ikke muligt at håndtere allokering af hukommelsen i JavaScript endnu(?)
User
Bruger #4304 @ 21.08.05 16:29
Fremragende artikel, sad selv og overvejede om man skulle skrive en artikel om prototype funktionen, da den også kan bruges på andre eksisterende objekter.
Jeg vil dog give Brian ret i, at det du kalder din klasse for contructor kan virke lidt forvirende, på folk der allerede kender til OOP i andre sprog.
Jeg tror heller ikke man kan styre sp meget med hvordan JavaScript håndtere allokering i hukommelsen, men kunne da forestille mig(ikke testet, et skud i tågen) at hvis man ikke brugte "new" ville den pege på det samme sted som klassen, i stedet for at oprette en hel ny klasse i hukommelsen(hvis nogen følger mig her, er lidt usikker).
User
Bruger #601 @ 03.09.05 09:15
Megt fin og brugbar gennemgang (selv om jeg ikke helt forstår din bemærkning om ikke så udbredt i Delphi ;-)).
User
Bruger #5620 @ 20.09.05 12:57
Det lidt noget sludder når du påstår der ikke er nogen forskel på hvordan du giver en klasse functioner og der er en tredje måde som jeg foretrækker :)
Som det ses illustreret i følgende kode kan man skrive en klasses functioner direkte ind i constructor functionen, og som det ses skaber den anden foreslået metode en extern function der kan kaldes uden om objekter af klassen og fylder op i namespace.


illustrerende kode håber jeg :)
function Test(){
this.func1=function(){
return 'func1';
}
this.func2=extFunc;
this.func4=intFunc;

function intFunc(){
return 'inrFunction';
}
}
Test.prototype.func3=function() {
return 'func3';
}
function extFunc(){
return 'extFunc';
}
T=new Test();
alert(T.func1());
alert(T.func2());
alert(T.func3());
alert(T.func4());
alert(extFunc());
User
Bruger #6546 @ 24.10.05 15:26
Det er en fin lille artikel.
Det gav mig lidt ideer. Har ikke prøvet OOP i javascript før, men jeg kastede en tabbar sammen, som jeg håber andre kan få gavn af:
http://udvikleren.dk/thread.php?techid=9&f=9&t=842
User
Bruger #9674 @ 29.11.06 16:43
Udmærket artikkel, ikke så dybde gående, og kræver erfaring for at kode, men eller udemærket...

Giver et godt indblik i OOP.
User
Bruger #10113 @ 26.02.07 16:21
Dårlig, jeg fattede ikke noget!
User
Bruger #10113 @ 26.03.07 16:10
Måske fordi jeg manglede interesse;)
User
Bruger #16685 @ 23.06.11 16:48
Tak til Jens P Svenson for det gode eksempel.
Du skal være logget ind for at skrive en kommentar.
t