Vous êtes sur la page 1sur 7

20/05/13

Programacin orientada a objetos en javascript Experimentando en la web

Experimentando en la web
Tutoriales,consejosydivagacionesdeunprogramadornovatoeneldesarrolloweb

BLOG

S O B RE E L A UTO R

TUTO RI A L E S JA V A S CRI P T

TUTO RI A L E S W E B G L

Programacin orientada a objetos en javascript


Escritoporjgrcel5abril,2012 POOProgramacin

CATEGORIAS
Programacin(32) Canvas2D(11) POO(2) webGL(19) three.js(3)

Bienvenidosaunnuevotutorialsobreelapasionantemundodeldesarrollodejuegosamateurenjavascript.Hoyhablar sobrecmoimplementarelparadigmadelaprogramacinorientadaaobjetos(deahoraenadelante,POO)delaforma menostraumicaposible,emulandoalasintaxisdeJavaalldondesepueda. EnlaprimeraleccindecmoprogramarelSpaceInvadershiceunaextensaintroduccinsobreunaprimerintentode POOenjavascript,perodondetenamosseriaslimitaciones,queveremosacontinuacin. Desgraciadamente,asumirquelosquesiganestetutorialtienenconocimientosbsicosdePOO.Enotrocaso,deberas deleerantesaqulprimertutorial,omejoran,aprenderPOOporotrasfuentesantesdeempezarconmistutoriales.

PRIMER INTENTO DE POO


Veamosalgunodelosejemplosquepuseenaquelprimertutorial.Laclasepadre: functionMiPrimeraClase(){ //Atributosdelaclase this.atributo1 this.atributo2 this.atributo3 //Construcordelaclase this.constructorBase=function(arg1,arg2,arg3){ this.atributo1=arg1 this.atributo2=arg2 this.atributo3=arg3 } this.constructor=function(arg1,arg2,arg3){ this.constructorBase(arg1,arg2,arg3) } //Mtodosdelaclase this.getAtributo1=function(){ returnthis.atributo1 } this.setAtributo1=function(valor){ this.atributo1=valor } //Aquiranmsgetterysettersdelosotrosatributos... this.metodo1=function(){ this.atributo1=this.atributo2+this.atributo3 } this.metodo2=function(arg1){ this.atributo3+=arg1 this.metodo1() } } Ylaclasequehereda: functionMiClaseHeredada(){ //Atributosnuevosdelasubclase this.atributo4 //Construcordelaclase this.constructor=function(arg1,arg2,arg3,arg4){ this.constructorBase(arg1,arg2,arg3) this.atributo4=arg4 } //Mtodosnuevosdelasubclase this.getAtributo4=function(){ returnthis.atributo4 }

LTIMAS ENTRADAS
Tutorialdealgoritmosenjavascript, backtrackingrecursivo:Cifrasyletras 13mayo,2013 TutorialdePongenJavaScriptII:UnaIA msavanzada. 30abril,2013 Usoprcticodevectores:Pong(yunpoco desonido) 10abril,2013 Three.jsTutorial3Texturas,iluminaciny transparencias. 5abril,2013 Three.jsTutorial2Colores,movimientosy 3D 6marzo,2013

Sieltutorialtehaservidodealgo,invtame aunacerveza!

www.jlabstudio.com/webgl/2012/04/programacion-orientada-a-objetos-en-javascript/

1/7

20/05/13

Programacin orientada a objetos en javascript Experimentando en la web

this.setAtributo4=function(valor){ this.atributo4=valor } this.metodo3=function(valor){ this.atributo4+=17 } } MiClaseHeredada.prototype=newMiPrimeraClase() Comosepuedever,unodelosproblemasmsgravesquepresentabamiprimerintentodePOOesquelasclaseshijas tienenproblemasparallamaralosmtodossobrecargadosdelaclasepadre(porejemplo,elconstructor).Dichoproblema loarreglbamoscambindoleelnombrealmtodoproblemticoenlaclasepadre,aadindoleporejemplounBase. Otroproblema,aunquedemenorimportancia,esquetampocoestabausandoatributosymtodosprivados.Todoseran pblicos.Unlector,Ramn,dejenuncomentarioindicandoqueenlapgina http://imbuzu.wordpress.com/2009/06/14/javascriptorientadoaobjetossegunbuzulosmetodos/mostrabancmo privatizarlasclases.

SEGUNDO INTENTO DE POO


Siguiendolasrecomendacionesdeeseltimoenlace,yutilizandoalgunasdelasnovedadesquevimoseneltutorialdel tiroparablico(losmtodosgetterysettermejorados,prescindirdelmtodoconstructor),podemosprogramar pefectamenteunaclaseconmtodosyatributostantopblicoscomoprivados. functionMiClaseMejorada(arg1,arg2,arg3,arg4){ varself=this //Atributospblicosdelaclase this.atributoPublico1=arg1 this.atributoPublico2=arg2 //Atributosprivadosdelaclase varatributoPrivado1=arg3 varatributoPrivado2=arg4 //GettersySetters this.get=function(atributo){ switch(atributo) { case"atributoPublico1": returnthis.atributoPublico1 case"atributoPublico2": returnthis.atributoPublico2 case"atributoPrivado1": returnatributoPrivado1 case"atributoPrivado2": returnatributoPrivado2 } } this.set=function(atributo,valor){ switch(atributo) { case"atributoPublico1": this.atributoPublico1=valor break case"atributoPublico2": this.atributoPublico2=valor break case"atributoPrivado1": atributoPrivado1=valor break case"atributoPrivado2": atributoPrivado2=valor break } } //Mtodospblicosdelaclase this.metodoPublico1=function(){ returnmetodoPrivado1()*2 } this.metodoPublico2=function(){ returnmetodoPrivado2()*3 } //Mtodosprivadosdelaclase varmetodoPrivado1=function(){ returnself.atributoPublico1+atributoPrivado1 } functionmetodoPrivado2(){ returnself.atributoPublico2+atributoPrivado2 } }

www.jlabstudio.com/webgl/2012/04/programacion-orientada-a-objetos-en-javascript/

2/7

20/05/13

Programacin orientada a objetos en javascript Experimentando en la web

//Parautilizarlaclase,podramosinicializarlaas(idnticoaJava): varmiClase=newMiClaseMejorada(1,2,3,4) Aprimeravista,pareceunasolucinbrillante.Losmtodosgetterysettertrabajanbien.Conunmtodopblico(por ejemploelget),podemosaccedertantoavariablespblicascomoprivadas.Cuandounmetodopblicoaccedeauna variableprivada,selesueleconocercomomtodoprivilegiado. Paraquedesdelosmtodosprivadossepudieraaaccederalosatributospblicos,hemoshechadomanodeunavariable privadallamadaSELF,porquecomoexplicardespus,elTHISnosiempreapuntaalainstanciadelobjetoqueseest ejecutandoenunmomentodado. Sinembargo,seguimosteniendoelproblemadelasobrecargademtodosconlaherencia.Sienlaclasehijacreamosun mtodoquesellameigualqueenlaclasepadre,peroquesinembargo,queremosqueelmtododelpadresigasiendo accesibledesdelaclasehija,tendramosquevolverausarlaprimitivayhorribletcnicadecambiarleelnombrealmtodo delpadre.

TERCER INTENTO (Y DE MOMENTO DEFINITIVO) DE POO


Perolosmayoresproblemasquepresentanlassolucionesanteriores,queporelmomentoignorbamos,sonelconsumo dememoriaytamaoquenecesitabacadaobjeto.JavascriptnoesJava,comoyahedichomuchasveces.Porlotanto, internamentelacreacindeobjetosnotrabajaigual.Dehecho,noseparecenennada.Cuandoinicializocualquierobjeto conunNEW,javascriptharunacopiaenmemoriadeltodoelcdigoinvolucradoenlaimplementacindeesafuncin. Recordadquelasclasesenrealidadlasdeclaramoscomofunciones.Todoslosatributosymtodosdeunaclaseestn contenidosenunanicafuncin,lacualdenominamosconelnombredelaclasequerepresenta.Asquesicreo100 objetos(haciendounnewaesafuncin),seclonartodoelcdigoquehaydentrodelafuncin100vecesendiferentes trozosdememoria,conelderrochedeRAMyeficienciaqueesoconlleva.Esciertoqueenlospequeosjuegosque hemoshechoporelmomento,nofueunfactordecisivonisiquieranosdimoscuenta.perocuandotengamos10.000 objetossobrelosqueaplicarmtodos,tenemosbastantepapeletasdequeeljuegofuncionemslentamenteconforme msmodestoseaelPCsobreelquecorre. Enrealidad,slonosinteresaquesecloneenmemorialosatributosdelasclases,yaquecontendrnlosvalores cambiantes(variables)quedistinguirnunainstanciadeotradeesamismaclase.(Nota:Enrealidadmerefieroaslolos atributosnoestticosdelaclase,peroparanocomplicardemasiadoeltutorial,dejaremoslasvariablesestticasparaotro da).Losmtodos,esdecir,sucdigo,esexctamenteelmismoparatodaslasinstanciasdeunamismaclase,porloque esabsurdoclonarloporcadaobjetoquedeclaremosennuestrapgina. Perotranquilos,hayunaformaelegantedeevitaresederrochedememoria:Usarelprototipado,queescomorealmente funcionaPOOenJavaScript.Deberarecordarquedemomento,elprototipadolousamosparahacerqueunasclases heredendeotras.Peroojo,aqullanofueunaformaptimadeusarlo,seguamosdesperdiciandomemoria,pues bsicamentehacamosquelaclasepadresecopiaradentrodelaclasehija.Enseguidaveremoscmohacerlomejor. Sinembargo,utilizarelprototipadotieneunprecio:Nosimpedircrearvariablesnimtodosprivados.Laculpalatienela clausura(digamosqueesunaespeciedembitodeexistenciadelasvariables)queseproducealcrearfunciones.En Javascripttodoslosobjetos(variablesyfunciones)pertenecenaunpadre.Losobjetosdeclaradosenlaraz,pordefecto pertenecenawindow.Losobjetosquedeclaresdentrodelasfunciones,pertenecenaesafuncin.Yassucesvamente. Assevaformandounaespeciederbol.Abrochagorda,losobjetosslosonaccesiblesenlasramasqueestnal mismonivelyqueseanhermanas(tenganelmismopadre).LapalabrareservadaTHISnohacereferenciaalobjetodonde seejecuta(comoenJava)sinoalpadredelafuncindondeestcontenida,porloquenosiempreTHISesunpunteroal objetoinstancia(poresoenlaclaseJuegodeltiroparablicotuvequecrearunavariablequesellamadaself).Fueradela funcinquehacedeclase,lasvariablesdeclaradasdeformaprivadaserninaccesibles.Inclusodentrodesta,siestn endiferentesniveles,tampoco. Enelintentoanterior,podamosdeclararatributosprivadosporquetodoelcdigoestabadentrodelafuncinquehacede clase.Sinembargo,comoveremosacontinuacin,partiremoslaclaseenvariostrozos(funciones)independientes, unindolasdespusentreellasmedianteelprototipado.Asquelasvariablesprivadasdeclaradasenalgunodelostrozos, nosernaccesiblesdesdealgunodelosotrostrozos.Lasvariablespblicas,notieneneseproblema.AlponerleselTHIS delante,hacemosquelasvariablessecreenenelpadre.Yenlosotrostrozosqueconformanlaclase,comoelpadrees elmismo,estarnaccesibles. Lacausaesdifcildeexplicar,yaunmsdifcilandeentendersimplementecreroslo.Elquenohayaquedado satisfecho,puedebuscarmsinformacinpreguntandoanuestroamigoGoogle,queporejemplo,nosdicecosascomo sta. Asqueospresentoaloqueapartirdeahorasermimodelodeclasesqueusarparajavascript,hastaqueencuentre algoquemegustems: //CLASEPADRE //Constructor functionMiPrimeraClase(arg1,arg2){ //Atributosdelaclase this.atributo1=arg1 this.atributo2=arg2 } //GettersySetters MiPrimeraClase.prototype.get=function(atributo){

www.jlabstudio.com/webgl/2012/04/programacion-orientada-a-objetos-en-javascript/

3/7

20/05/13

Programacin orientada a objetos en javascript Experimentando en la web

switch(atributo) { case"atributo1": returnthis.atributo1 case"atributo2": returnthis.atributo2 } } MiPrimeraClase.prototype.set=function(atributo,valor){ switch(atributo) { case"atributo1": this.atributo1=valor break case"atributo2": this.atributo2=valor break } } //Mtodos MiPrimeraClase.prototype.metodo1=function(){ this.atributo1+=10 } Comopodemosobservar,laclaseestpartidaen4funciones.Laprimeraserlaquecrealaclase,queademsnos servircomoconstructor.Lepasamosunpardeargumentos,parainiciarsusdosatributos. Acontinuacin,creamossugetterysetter,siguiendolamejoraquevimoseneltutorialdeltiroparablico,yaprovechando eltipadoblandoqueusajavascript. Porltimo,declaramosunmtodoquesimplementeincrementaen10unidadesunodelosatributosdelaclase. Loquenosinteresaaprenderdesteejemploesvercmoseusaelprototipado.Yadijequelasvariablesyfuncionesde javascriptsonobjetos.Elprototypesirveparaextenderlafuncionalidadatodaslasinstanciasdeeseobjeto,pero compartiendoelmismocdigocontodosellos,queesjustoloquemsnosinteresabaconseguir.Asqueusandola palabrareservadaPROTOTYPE,extenderemoselprototipodelafuncin(clase)MiPrimeraClase. Paraverloanmsclaro,hagamoslaejecucinmentaldelsiguientecdigo: window.onload=function(){ varmiClase=newMiPrimeraClase(1,2) varmiClase2=newMiPrimeraClase(3,4) miClase.set("atributo2",5) alert(miClase.get("atributo2")) alert(miClase2.get("atributo2")) } Paraempezar,laconsoladeJavascriptleeralostrozosdecdigoqueformanlaclase,ylosmeteraenmemoria. Acontinuacin,seejecutaraenonloaddelobjetowindows. LasdosprimeraslneascorrespondenalacreacineinicializacindedosinstanciasdenuestraclaseMiPrimeraClase, pasndolelosdosargumentosquenecesitaelconstrutor.ExctamenteigualqueharamosconJava(salvoconunapega, nopodemosdeclararmsconstructores,parasimularsobrecargadeconstructores,habraquejugarconlosargumentos quenosllegan,talycomodijeenlaprimerapartedeltutorialdelSpaceInvaders).Loqueharalaconsoladejavascript seraclonarenmemoriadosveceslafuncinMiPrimeraClase,cadaunaconlosatributosinciadosalvalorcontenidoen suscorrespondientesargumentos.Yaquestelquiddelacuestin:Noclonaelrestodemtodos,porquelafuncin MiPrimeraClaseenrealidadnoloscontiene(comohacamosantes). Sinembargo,graciasalprototipado,cuandoejecutamoselsetsobreelobjetomiClase,laconsoladeJavaScriptbuscar eltrozodememoriadelafuncingetasociadamedianteprototipadoalobjetoMiPrimeraClase,cambindoleaselvalor delatributollamadoatributo2. Porltimo,losdosgetqueusamosenlosalerttrabajandelamismaforma.Cadaunomostrarelvalordelatributo atributo2asociadoasuinstancia,mostrandolosvalorescorrectos(5y4). Peroyqupasaconlaherencia?Vemoslasiguienteclase,queheredardeMiPrimeraClase: //CLASEQUEHEREDAR //Constructor functionMiClaseHeredada(arg1,arg2,arg3){ //Atributosdelaclase MiPrimeraClase.call(this,arg1,arg2)//Llamadaalconstructordelaclasepadre this.atributo3=arg3 } //HERENCIA MiClaseHeredada.prototype=newMiPrimeraClase //GettersySetters

www.jlabstudio.com/webgl/2012/04/programacion-orientada-a-objetos-en-javascript/

4/7

20/05/13

Programacin orientada a objetos en javascript Experimentando en la web

MiClaseHeredada.prototype.get=function(atributo){ switch(atributo) { case"atributo3": returnthis.atributo3 default: returnMiPrimeraClase.prototype.get.call(this,atributo)//Llamadaalgetdelaclasepadre } } MiClaseHeredada.prototype.set=function(atributo,valor){ switch(atributo) { case"atributo3": this.atributo3=valor break default: MiPrimeraClase.prototype.set.call(this,atributo,valor)//Llamadaalsetdelaclasepadre break } } Comovemos,laclasetambinestpartida,en4trozos.Elprimero,comoanteseselconstructor.Perofijmonosantes enelsegundotrozo,queesslounalnea:AsescomohacemosqueMiClaseHeredadaherededeMiPrimeraClase.Es decir,quelosmtodosdelprototipadodeMiPrimeraClasetambinpertenezcanalprototipadodelaclase MiClaseHeredada.Simplementememorzaloyaplcalodeaquenadelante. Volvamosalconstructor.Nuestraclasedeclaraunnuevoatributoatributo3,asiquejuntoalosatributosqueheredamos delaclasepadre,hacequeelconstructorrequierade3argumentosparainicializarlosconalgnvalor. Podramoshaberhechosimplementeunthis.atributo1=arg1this.atributo2=arg2this.atributo3=arg3peroparaqu repetircdigoqueyahaceelconstructordelpadre?Asqueusandoelprototipadopodemoshacerunallamada(mtodo CALL)alconstructordelaclasepadre.Notepreocupesporentendercmofunciona.Tebastaconsaberquenecesitaal menosunargumento:Elobjetosobreelqueejecutarlafuncinalaqueestamosllamando.Enestecaso,elTHIS,para quelosatributoscreadosporelconstructordelpadresecreentambinenlaclasehijaquehacelallamada.Elrestode argumentos,simplementeseconcatenarncomoargumentosalafuncinsobrelaqueseaplicaelCALL.Ycomola funcinalaqueestamosllamandoeselconstructor,querequierededosargumentos,sonlosargumentosquetambin (enelordencorrecto)lepasamosalCALL.EsunaformaelegantedesimularelutilsimoSUPERdeJava,conuna mejora:Situviramosunajerarquadeclasesdemsdedosniveles,podramosllamaralconstructordelabuelo directamente,algoqueconJavanosepuedehacer. Despusdelconstructorydelaherencia,vienenlosmtodosgetterysetter.Comprobamossielatributosobreelque trabajareselalgunodelosquehemosdeclaradoenestaclase.Sinoesas,llamamosalGEToSETdelaclasepadre(a travsdelprototype,yaqueadiferenciadelconstructor,aqulloseranmtodosprototipados)conlosargumentos adecuados.Yas,evitamosduplicarcdigo. Porltimo,yparamostrarquestofunciona,probemoselsiguientecdigo: window.onload=function(){ varclaseHeredada1=newMiClaseHeredada(1,2,3) varclaseHeredada2=newMiClaseHeredada(4,5,6) alert(claseHeredada1.get("atributo3")) claseHeredada1.set("atributo1",10) alert(claseHeredada1.get("atributo1")) claseHeredada2.metodo1() alert(claseHeredada2.get("atributo1")) } Consteejemplocomprobaremosquetodofunciona:Queelconstructordelaclasehijainicializacorrectamentelos atributosdelaclasepadre,queelgetysetdelaclasehijallamacorrectamentealdelaclasepadre,yqueelmtodo metodo1delaclasepadreesaccesibleenlaclasehija.Sitodomarchabien,semuestra1,10y14. Ycontodasestasenseanzas,yadisponesdeunaestupendaformadeimplementarPOOentusfuturoscdigos mejorandoconellolaampliacinymantenimientodetusprogramasweb.Apartirdeahora,serlafilosofaqueseguir paraprogramarlossiguientestutoriales. Etiquetas:javascript,programacionorientadaobjetos

BrunoMichelSanchez
8deabrilde2012alas18:38

Exelenteamigo!!

BrunoMichelSanchez
8deabrilde2012alas23:59

www.jlabstudio.com/webgl/2012/04/programacion-orientada-a-objetos-en-javascript/

5/7

20/05/13

Programacin orientada a objetos en javascript Experimentando en la web


unbuenotutosobrecomopuedomanejarcanvasmehariabien!!

PatrickSvensson
25deabrilde2012alas09:27

Muybuenostutorialesymuysencillosdeentender.MegustararecomendarteenTwitterperonohevistotu nombreporningnsitio. Unsaludo.

jgrc
28deabrilde2012alas20:20

Mealegradequetegustenlostutoriales,esperoquelesirvandealgoamsdeuno. Notengocuentadetwitter,ysteesmiprimerblog,asiquesupongoqueeslonicoquedemomento puedocompartir.

Gerard
12deagostode2012alas19:13

Muchasgracias.Contutorialescomoestoslacosasehaceunpocomsfacil

Gerard
12deagostode2012alas19:24

SololeveuunproblemaalamanerafinaldeimplementarlaPOO,yesquepierdeslaposibilidaddetener propiedadesprivadas.Esdecir,entuejemplo,atributo1yatributo2siempreseranaccesiblesexternamente. Saludos.

JuanPablo
7deoctubrede2012alas21:32

Gerard,leeestafraserescatadadeltexto:Sinembargo,utilizarelprototipadotieneunprecio:Nosimpedir crearvariablesnimtodosprivados. SemehacemsdifcilverPOOenJS,noasenJavayPHP5.JavascriptmerecuerdaalSTRUCTen C++.

jose
24demarzode2013alas11:25

Eltutoestamuybuenofelicidades.Perosinceramentejsapesta.Aversiseespavilanylomejoranparaque podamksdisfrutardeunlenguajeestructuradoycontodaslasposivilidadesdeunlenguajepoo.

ALdo
20deabrilde2013alas23:29

GranpartedeloslenguajesORIENTADOSAOBJETOSutilizanlapalabraclass,porquejavascriptnolo deberiautilizar,envezdeusarartificios.Deberiahacernosfcillavidaalosprogramadoresenestospunto desintaxis. EsperoqueDARTdegoogletengabuenaacogidaoquejavascriptimplementenuevasntaxis. Buentutorial.

Nombre(obligatorio)

Email(noserpublicado)(obligatorio)

Pginaweb(sitienesuna)

Comentario

www.jlabstudio.com/webgl/2012/04/programacion-orientada-a-objetos-en-javascript/

6/7

20/05/13

Programacin orientada a objetos en javascript Experimentando en la web

Enviarcomentario TutorialdeTiles1parte,elprimermapa Fsicaen2D,eltiroparablico


GestionadoconWordpressyStripesTheme Entradas(RSS)|Comentarios(RSS)

www.jlabstudio.com/webgl/2012/04/programacion-orientada-a-objetos-en-javascript/

7/7

Vous aimerez peut-être aussi