Diferencia entre revisiones de «Programación en JavaScript/OOP»

De Wikilibros, la colección de libros de texto de contenido libre.
Sin resumen de edición
m Programación en JavaScript/OOP trasladada a Programación en JavaScript / OOP
(Sin diferencias)

Revisión del 22:24 18 jul 2005

Clases y objetos.

Dentro de los lenguajes actuales, que provienen en su mayoría de los primeros lenguajes estructurados como ALGOL o BCPL, la capacidad de crear funciones para reutilizarlas de diversas formas, ya sea dentro del mismo módulo del programa o en distintos módulos, ha sido uno de los fundamentos de la programación de sistemas informáticos. Sin embargo, este paradigma se quedaba corto para nuevas situaciones que iban surgiendo con el tiempo, como la programación de videojuegos o el 3D y la inteligencia artificial. A finales de los años 70 se comenzó a teorizar sobre lenguajes de programación que utilizasen entidades independientes que fueran autocontenidas para realizar las aplicaciones. Como ya dijimos anteriormente, un programa se compone de código y datos. los objetos son unidades que contienen su propio código y datos para su propio auto-funcionamiento. Podemos decir que son programas dentro de programas.

Dicho así, podemos darnos cuenta de que los objetos pueden ser utilizadas en variables, para nuestro propio uso. Pero no podemos definir variables de objeto sin poder darles una forma. La forma de los objetos son los datos (propiedades) y código (funciones) que contiene el objeto. A esto se le denomina clase de objeto. Para definir clases en JavaScript, lo hacemos por medio de funciones, como esta:

   function Persona(nombre) {
           this.nombre = nombre;
           this.color_pelo = 'negro';
           this.peso = 75;
           this.altura = 165;
           this.sexo = 'varón';
   }

Vamos a fijarnos bien como se estructura esta función. Se le llama constructor de la clase, y en ella definimos los datos de la clase, los que vamos a poder utilizar al crear objetos con ella. Nótese el uso de la palabra reservada this. Esta palabra sirve para identificar al objeto en si mismo dentro de la definición de la clase. Cuando escribimos

   this.peso = 75;

estamos creando la propiedad "peso" de la clase "Persona". Cuando creamos una propiedad en el constructor y le damos un valor, como en este caso, estamos asignándole un valor por defecto. Todos los objetos creados con este constructor contendrán una propiedad "peso" con ese valor inicial, aunque luego podremos cambiarlo al usar el objeto. Para definir un objeto de esta clase, sólo tendríamos que hacer esto:

   var hombre = new Persona('Pepe');

Aquí hemos definido el objeto "hombre", que contendrá todas las propiedades definidas en la función-clase "Persona". Si queremos cambiar su valor, sólo tenemos que hacer algo como esto:

   hombre.peso = 80;

De esta forma, el dato definido para este objeto cambia. Pero si hemos definido más objetos de tipo Persona, cada uno de ellos contendrá las mismas propiedades pero con valores distintos. Ningún objeto tiene el mismo valor que otro objeto de la misma clase a no ser que nosotros se lo asignemos explícitamente.

   var mujer = new Persona('Ana');
   mujer.peso = 67;

En este caso hemos hecho lo mismo, pero le indicamos su propio peso, independiente del de la variable "hombre". Así, podemos tener tantos objetos de la misma clase como queramos para realizar las operaciones que sean pertinentes. Una última cosa sobre los constructores: como podemos ver, podemos pasarle parámetros, que podemos convertir en los valores de las propiedades de los objetos de esa clase.

Creación de funciones miembro.

Hasta ahora hemos visto como crear propiedades de las clases, pero necesitamos crear código en ese objeto que utilice las propiedades que hemos creado en el constructor. Para crear una función miembro, debemos indicarlo en la propia función de construccion:

   function Persona(nombre) {
           this.nombre = nombre;
           this.color_pelo = 'negro';
           this.peso = 75;
           this.altura = 165;
           this.sexo = 'varón';
           this.dormir = dormir; // Nueva función miembro
   }

Y ahora definimos la función dormir:

   function dormir() {
           alert(this.nombre + ' está durmiendo');
   }

Fijémonos en la función. Tiene una forma bastante normal. Lo único especial que hemos hecho es añadir la linea

   this.dormir = dormir;

al constructor, con lo que hemos asignado la función dormir como si fuera una propiedad. Recordemos que TODO es un objeto en JavaScript, y esto incluye a las funciones. Ahora, para ejecutar este código, utilizamos el objeto anteriormente creado para ponerlo en marcha:

   hombre.dormir();

Veamos en un ejemplo todo el código que hemos generado hasta ahora:

   <html>
   <head>
   <script language="javascript">
   function Persona(nombre) {
       this.nombre = nombre;
       this.color_pelo = 'negro';
       this.peso = 75;
       this.altura = 165;
       this.sexo = 'varón';
       this.dormir = dormir;
   }
   
   function dormir() {
           alert(this.nombre + ' está durmiendo');
   }
   </script>
   </head>
   
   <body>
   <form>
   </form>
   <script>
       var hombre = new Persona('Pepe');
       hombre.dormir();
   </script>
   </body>
   </html>

Como resultado, nos mostrará el mensaje "Pepe está durmiendo". Como vemos, podemos usar las propiedades de los objetos dentro de las funciones miembro, aunque también podríamos construir la misma funcion de otra manera:

   function dormir() {
       with (this)
           alert(nombre + ' está durmiendo');
   }

with es una palabra reservada de JavaScript que permite coger una variable de objeto como this y permite utilizar sus miembros como si fueran variables independientes. Pero tiene sus restricciones: estos nombres abreviados sólo se pueden utilizar dentro del ambito de with (que si tiene varias lineas, estas deben estar contenidas entre llaves, como for, if, etc...), y además, se pueden confundir facilmente con variables locales a la función o globales del programa, con lo cual particularmente no recomendamos el uso de with, ya que puede dar lugar a fallos de ejecución dificiles de tratar si no se tienen en cuenta estas restricciones. Se aconseja usar la forma this.nombre. También se recomienda crear cada clase en un archivo diferente para que no haya confusiones de nombres, sobre todo de funciones miembro.