/ janturon.cz / Od kodéra k analytikovi / Objektové programování v Javascriptu

Objektové programování v Javascriptu

Jelikož funkce je v javascriptu first-class citizen a nedefinuje třídy, k objektovému programování si pomáhá functory z funkcionálního programování. Další kapitoly se týkají převážně objektového programování, proto je zde Javascriptový přístup ve stručnosti vysvětlen.

Javascript nemá třídy, ale má objekty. Objekt se vytváří konstrukcí new Object(); nebo kratčeji pomocí {} (speciální objekt pole lze zapsat jako new Array() nebo []).

Konstruktor lze zapsat jako new function(params), kde operátor new vytvoří objekt obsahující členy odkazované pomocí this uvnitř funkce (návratová hodnota funkce je při použití new ignorována, new tak dělá z funkce objekt, functor).

// functor function One(x) { this.x = x; this.info = function() { alert(this.x); } return x; } var a = One(42); // volání funkce var b = new One(42); // tvorba objektu

Zapouzdření

Členy functoru uvedené jako this. jsou veřejné, členy uvozené var jsou privátní.

Dědičnost

Pomocí funkce call nebo apply je možné zavolat ve functoru jinou funkci a předat ji kontext, tzn. všechny členy volané funkce jsou přejaty do functoru. To je ekvivalentní volání konstruktoru děděné třídy:

// dědění z One function Two(x,y) { One.call(this,x); this.y = y; this.info = function() { alert(this.x+","+this.y); } } var c = new Two(1,2); c.info(); // 1,2

Javascript tedy podporuje vícenásobnou dědičnost (funkci call můžeme volat vícekrát).

Dynamická vazba

Javascript je slabě typovaný jazyk, vyhodnocení typu jedy probíhá vždy až za běhu. Navíc pomocí prototypování je možné přidat člen již definovanému functoru. Functory "dědí" (překrývají členy) svých prototypů:

// prototypování function Three(z) { this.z = z; } Three.prototype = new Two(3,4); Three.prototype.info = function() { // this.x a this.y existuje: vyhodnoceno za běhu alert(this.x+","+this.y+","+this.z); } var d = new Three(5); var e = new Three(6); e.x = 2; d.info(); // 3,4,5 e.info(); // 2,4,6

Polymorfismus

Functory obsahují člen arguments, což je pole argumentů. Toho lze využít k definování různých implementací funkcí v závislosti na počtu zadaných argumentů. (Javascriptu nevadí, zadáme-li jiný počet argumentů než je uveden v deklaraci: do nevyplněných se vloží undefined, nadbytečné se ignorují bez vyvolání chyby.)

// funkční polymorfismus function say() { var args = arguments; if(args.length==1) say1(args[0]); else if(args.length==2) say2(args[0],args[1]); } function say1(p) { alert("I say "+p); } function say2(p,q) { alert("I don't say "+p+" nor "+q); } say("hello"); // say1 say("good","bad"); // say2

Polymorfismus rozhraní lze zapsat opět pomocí call:

// polymorfismus rozhraní function Kid(name) { this.name = name; } function Boy(name) { Kid.call(this,name); } function Girl(name) { Kid.apply(this,[name]); } Kid.prototype.hello = function() { return this.name+" is a "; } Boy.prototype.hello = function() { return Kid.prototype.hello.call(this) + "boy"; } Girl.prototype.hello = function() { return Kid.prototype.hello.apply(this) + "girl"; } var bob = new Boy("Bob"); var ann = new Girl("Ann"); alert(bob.hello()); // Bob is a boy alert(ann.hello()); // Ann is a girl

Pozn.: Zatímco u call se předá druhý, třetí, čtvrtý... parametr jako první, druhý, třetí... parametr volané funkci, apply má pouze dva parametry: ten druhý je pole, jehož prvky se v tom pořadí předají. Krom prvního jsou další parametry těchto funkcí nepovinné.