JavaScript como Orientaci´on a Objetos
Gustavo Lacoste (
[email protected])
October 2012
Resumen
El objetivo de las siguientes notas es generar una estructura en JavaScript
que nos permita reutilizar de manera limpia las funciones creadas en otros
ficheros JavaScript, para esto reorganizaremos el c´odigo intentando aprox-
imarnos al concepto de clase tomando como base su implementaci´on en el
lenguaje de programaci´on orientado a objetos PHP.
Palabras Clave: JavaScript, Orientaci´on a Objetos, JSON, Funciones an´onimas,
Funciones autoejecutables, PHP.
JavaScript NO es un lenguaje Orientado a Objetos, es en realidad el ´unico
lenguaje de programaci´on basado en herencia de prototipos [2]. A pesar que
encontramos el uso de los operadores new y this dentro de c´odigos JavaScript,
estos operadores no hacen exactamente lo mismo que en los lenguajes Orien-
tados a Objetos. Por una parte this en realidad cambia su comportamiento
dependiendo del contexto y por otra parte new genera una instancia del objeto
referido aunque la instancia puede ser extendida en el futuro mediante el uso
de prototype, estos operadores act´uan como una fachada que hace parecer el
lenguaje como orientando a objetos a´un cuando su funcionamiento es diferente
al de los lenguajes Orientado a Objetos tradicionales.
La raz´on por la cual JavaScript intenta esconder su verdadera naturaleza
detr´as de una fachada cl´asica de POO es la complejidad que representa la com-
prensi´on de un nuevo paradigma particular para este lenguaje. La idea de dis-
frazar el uso de JavaScript bajo la apariencia t´ıpica del paradigma Orientado
a Objetos no es nueva, por un lado la academia cl´asica ense˜na a los nuevos
programadores todos los conceptos cl´asicos de Orientaci´on a Objetos y mode-
lado de software (mediante UML [3]), dejando poco espacio para la discusi´on
de otros paradigmas; parece l´ogico entonces intentar disfrazar JavaScript con
la apariencia de POO en post de una comprensi´on m´as r´apida y pr´actica del
lenguaje.
A continuaci´on intentaremos mostrar una sint´axis que se asimile lo m´as
posible a la cl´asica orientaci´on a objetos utilizando los elementos existentes
en JavaScript. En UML (Unified Modeling Language) una forma b´asica para
representar la clase Persona ser´ıa:
1
JavaScript como Orientaci´on a Objetos
Seg´un este diagrama una clase (molde) para construir objetos Personas se
caracteriza entre otras cosas por:
El atributo nombre de tipo String y de acceso privado (es decir s´olo puede
ser accedido y modificado por m´etodos de la propio objeto que se cree a
partir de la clase) de la misma forma el m´etodo pensar() s´olo puede ser
llamado desde m´etodos de la clase.
Los m´etodos setNombre y getNombre son p´ublicos es decir pueden ser
llamados desde fuera de la clase, en la pr´actica dichos m´etodos que ser´an
parte del objeto que instanciemos a partir de la clase podr´an ser visibles
desde otros objetos pero no as´ı aquellos atributos o m´etodos privados.
Para realizar una comparaci´on realista vamos a escribir la clase con uno de los
lenguajes Orientados a Objetos m´as utilizados por los desarrolladores web: PHP
(acr´onimo de PHP: Hypertext Preprocessor ). PHP es b´asicamente un lenguaje
de scripting dise˜nado para generar c´odigo HTML y enviarlo al navegador web
del cliente, es por tanto un lenguaje de programaci´on que se utiliza de lado del
servidor.
El caso de PHP es diferente, dado que el lenguaje fu´e originalmente dise˜nado
para realizar scripts estructurados, en PHP es posible programar tanto de man-
era estructurada como Orientada a Objetos. En siguiente c´odigo representa la
declaraci´on de la clase Persona en PHP:
1 <?php
2 c l a s s Persona {
Listing 1: persona.php
p r i v a t e $nombre ;
p u b l i c f u n c t i o n getNombre ( ){
$ t h i s−>p e n s a r ( ’ Entrego mi nombre<br/> ’ ) ;
r e t u r n $ t h i s−>nombre ;
}
p u b l i c f u n c t i o n setNombre ( $nombre ){
$ t h i s−>p e n s a r ( ’ Cambio mi nombre<br/> ’ ) ;
$ t h i s−>nombre=$nombre ;
}
p r i v a t e f u n c t i o n p e n s a r ( $pensamiento ){
}
echo $pensamiento ;
3
4
5
6
7
8
9
10
11
12
13
14
15 }
JavaScript como Orientaci´on a Objetos
16
17 $ g u s t a v o = new Persona ( ) ;
18 $gustavo−>setNombre ( ” Gustavo ” ) ;
19 echo ’ Mi nombre e s
’ . $gustavo−>getNombre ( ) . ’<br/> ’ ;
20
21 $ j u a n e l o = new Persona ( ) ;
22 $ j u a n e l o−>setNombre ( ” Juan ” ) ;
23 echo ’ Mi nombre e s
24 ?>
’ . $ j u a n e l o−>getNombre ( ) . ’<br/> ’ ;
en esta implementaci´on mediante PHP podemos diferenciar claramente la
declaci´on de las variables y m´etodos. A diferencia en el caso de JavaScript los
objetos pueden contener sus propios m´etodos sin necesidad de clases. Quiz´a una
de las formas m´as simples de generar una estructura similar a la anterior en
JavaScript es hacer uso de la notaci´on literal de declaraci´on de objetos en la que
un objeto es declarado como un conjunto desordenado de pares nombre/valor.
En esta forma de declaraci´on de un objeto a menudo conocida como JSON[1],
un objeto comienza con (llave de apertura) y termina con (llave de cierre). Cada
nombre es seguido por : (dos puntos) y los pares nombre/valor est´an separados
por , (coma). El flujo se ve representado en el siguiente diagrama:
Siguiendo esta l´ogica podr´ıamos declarar un objeto de forma literal en JavaScript.
Adem´as una particularidad de JavaScript es la de asignar una funci´on al val-
or de una variable, puediendo esta ser incluso an´onima por lo tanto podr´ıamos
tomar esta estructura y asignar a las variables que deseamos ver como m´eto-
dos una funci´on en lugar de un valor fijo (String, entero, etc) de esta forma
podr´ıamos llamar a esta funci´on an´onima llamando en realidad al nombre de
la variable a la cual le asignamos la funci´on an´onima. Otra caracter´ıstica in-
teresante del uso de funciones en JavaScript es que nos permite pasar funciones
como par´ametros a otras funciones, y obtener funciones como resultados de la
ejecuci´on de una funci´on.
La implementaci´on quedar´ıa como sigue:
JavaScript como Orientaci´on a Objetos
Listing 2: persona.js
Listing 3: persona adv.php
1 <?php
2 c l a s s Persona {
1
4
2 var Persona = {
nombre : " " ,
getNombre :
3
function ( ){
t h i s . p e n s a r ( ’ Entrego (cid:32) mi (cid:32) nombre < br / > ’ ) ;
return t h i s . nombre ;
} ,
setNombre :
function ( nombre ){
t h i s . p e n s a r ( ’ Cambio (cid:32) mi (cid:32) nombre < br / > ’ ) ;
t h i s . nombre=nombre ;
} ,
p e n s a r :
}
function ( p e n s a m i e n t o ){
document . w r i t e ( p e n s a m i e n t o ) ;
5
6
7
8
9
10
11
12
13
14
15 } ;
16
17 Persona . setNombre ( " Gustavo " ) ;
18 document . w r i t e ( ’ Mi (cid:32) nombre (cid:32) es (cid:32) ’+Persona . getNombre ( ) ) ;
p r i v a t e $nombre ;
p u b l i c f u n c t i o n getNombre ( ){
$ t h i s −>p e n s a r ( ’ Entrego mi nombre<br/> ’ ) ;
r e t u r n $ t h i s −>nombre ;
}
p u b l i c f u n c t i o n setNombre ( $nombre ){
$ t h i s −>p e n s a r ( ’ Cambio mi nombre<br/> ’ ) ;
$ t h i s −>nombre=$nombre ;
}
p r i v a t e f u n c t i o n p e n s a r ( $ p e n s a m i e n t o ){
}
echo $ p e n s a m i e n t o ;
3
4
5
6
7
8
9
10
11
12
13
14
15 }
16
17 $ g u s t a v o = new Persona ( ) ;
18 $gustavo−>setNombre ( ” Gustavo ” ) ;
19 echo ’ Mi nombre e s
20
21 $ j u a n e l o = new Persona ( ) ;
22 $ j u a n e l o−>setNombre ( ” Juan ” ) ;
23 echo ’ Mi nombre e s
24 ?>
’ . $gustavo−>getNombre ( ) . ’<br/> ’ ;
’ . $ j u a n e l o−>getNombre ( ) . ’<br/> ’ ;
1 <html>
2
<head>
Listing 4: index.html
<s c r i p t type=” t e x t / j a v a s c r i p t ” src=” p e r s o n a . j s ”></ s c r i p t>
3
4
5
</head>
<body>
</body>
6
7 </html>
JavaScript como Orientaci´on a Objetos
Resultado de la ejecuci´on con JavaScript:
Resultado de la ejecuci´on con PHP:
Si bien con ambas implementaciones (en PHP y en JavaScript) se obtiene
el mismo resultado (para un ´unico objeto) la implementaci´on en JavaScript es
s´olo una declaraci´on de un objeto. Esto significa que no existe un molde des-
de el cual generamos los objetos sino que simplemente delcaramos un objeto
inmeditamente, por otra parte tambi´en observamos que todos los m´etodos son
de hecho p´ublicos, necesitamos que al igual que en PHP la implementaci´on del
m´etodo pensar sea accesible s´olo por el propio objeto y no de forma p´ublica.
Si bien la forma de declaraci´on de objetos de JavaScript es la m´as simple
y f´acil de comprender sobre todo por su relaci´on directa con el formato JSON
no es la forma m´as conveniente de hacerlo para este caso dado que los nombres
de los atributos son siempre p´ublicos. Una forma simple de acernos a´un m´as es
hacer uso de las funciones autoejecutables de JavaScript (function() ...)();,
este tipo de funciones se ejecutan autom´aticamente al ser interpretadas y nos
servir´an para hacer uso del operador new de JavaScript de tal forma que la fun-
ci´on autoejecutable retorne en realidad un objeto con los m´etodos p´ublicos que
queremos que sean visibles solamente, manteniendo en su interior los m´etodos
privados. La implementaci´on basado en esta idea quedar´ıa as´ı:
JavaScript como Orientaci´on a Objetos
Listing 5: persona adv.js
1 window . Persona = window . Persona | | {} ;
2 window . Persona = ( function ( ) {
Listing 6: persona adv.php
1 <?php
2 c l a s s Persona {
" use (cid:32) strict " ;
function Persona ( ) {
}
var nombre = " " ;
Persona . p r o t o t y p e . getNombre = function ( ) {
p e n s a r ( ’ Entrego (cid:32) mi (cid:32) nombre < br / > ’ ) ;
return t h i s . nombre ;
} ;
Persona . p r o t o t y p e . setNombre = function ( nombre ) {
p e n s a r ( ’ Cambio (cid:32) mi (cid:32) nombre < br / > ’ ) ;
t h i s . nombre=nombre ;
} ;
function p e n s a r ( p e n s a m i e n t o ){
document . w r i t e ( p e n s a m i e n t o ) ;
}
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
return P
Comentarios de: JavaScript como Orientación a Objetos (0)
No hay comentarios