Canal RSS

JavaScript Orientado a Objetos

Publicado en

JavaScript es un lenguaje orientado a objetos, pero no es muy fácil comprenderlo en este aspecto. A pesar de la sintaxis y el nombre, la forma en que JavaScript implementa objetos es bastante diferente al que conocemos de C++ o Java, esto suele llevar a la confusión. Mi intención es describir como es que se trabaja con OOP en JavaScript intentando no confundir al compararlo con otros lenguajes.

Creación de Objetos

En JavaScript, todas las variables hacen referencia a objetos, no existe nada en este lenguaje que no sea un objeto, lo son todos los tipos de datos e inclusive las funciones, que pueden contener propiedades y métodos.

Para crear un objeto desde cero basta con hacer:

miobjeto = new Object();

Lo que equivale a hacer:

miobjeto = {};

La primera forma de declarar un objeto les puede resultar familiar, la segunda hace uso de una característica propia del lenguaje para declarar estructuras de datos. Todos los tipos de datos pueden declararse de las dos maneras, por ejemplo, una cadena de texto se declara:micadena = new String();

Y de la forma declarativa:micadena = “”;

Un array se declara:miarray = new Array();

Ó también:miarray = [];

Esta forma de declarar objetos es muy útil en algunos casos y es la base del intercambio de mensajes mediante el estándar JSON.

Agregar miembros

Javascript es un lenguaje dinámico, esto posibilita la modificación de los objetos en tiempo de ejecución, esto quiere decir que a un objeto, luego de ser creado, se le pueden agregar o eliminar métodos y propiedades.

Para agregar miembros al objeto creado anteriormente solo basta con declararlo y asignarle algún valor.

miobjeto.variable = “hola”;

miobjeto.metodo = new Function();

Listo, ya disponemos de un objeto personalizado creado desde cero, de este modo se pueden agregar mas miembros de cualquier tipo a nuestro objeto. Sin embargo, crear objetos de esta manera no es muy cómodo, ya que si quisiéramos crear una copia de este objeto deberíamos declarar nuevamente todos sus miembros, debido a que este objeto no se puede instanciar.

Creando ‘Clases’ en JavaScript

La forma en que los lenguajes orientados a objetos comúnmente resuelven el problema anterior es mediante el uso de Clases, en JavaScript no es posible declarar Clases, pero si es posible instanciar objetos a partir de un constructor.

El objeto Function es utilizado como objeto instanciable en JavaScript, y el cuerpo de la función es el constructor del nuestros objetos. Una vez que tenemos un constructor, podemos llamarlo con el operador new.

/*clase de ejemplo*/

miClase = new Function();

nuevoObjeto = new miClase(); // instanciamos ‘miClase’

El método mas difundido para emular las clases en JavaScript es aprovechar el funcionamiento de la palabra clave this dentro de los constructores. Cuándo una función es llamada con el operador new, this hace referencia al objeto que será retornado. Veamos como funciona.

/*clase de ejemplo*/

miClase = function(){

/*

agregamos miembros dinamicamente

al objeto que será retornado

*/

this.propiedad = “hola!”;

this.metodo = function(){

/* aqui ‘this’ hace referencia al objeto al que pertenece el metodo */

alert(this.propiedad);

}

}

nuevoObjeto = new miClase(); // instanciamos ‘miClase’

Ahora, ‘nuevoObjeto’ va a referenciar al objeto que se retornó cuando se llamó a ‘miClase’ usando el operador new, por lo tanto, va a tener todas las propiedades y metodos que se crearon dentro del constructor.

El problema de esta forma de crear clases es que cada vez que la función ‘miClase’ es llamada, se crea una nueva función llamada ‘metodo’, de modo que cada objeto tiene su propia versión de ‘metodo’ cuando, en realidad, todos los objetos deberían compartir la misma función.

La propiedad ‘Prototype’

Todas las funciones tienen una propiedad llamada prototype, esta propiedad es un objeto que será utilizado como ‘modelo’ inicial de todos los objetos que sean creados con esta función cuando sea utilizada como constructor.

Inicialmente esta propiedad es un objeto vacío, pero debemos modificarla para aprovechar esta característica del lenguaje. Reescribiendo el ejemplo anterior el código quedaría así:

/* creamos un constructor limpio */

miClase = new Function();

miClase.prototype.propiedad = “hola!”;

miClase.prototype.metodo = function(){

/* aqui ‘this’ hace referencia al objeto al que pertenece el metodo */

alert(this.propiedad);

}

nuevoObjeto = new miClase(); // instanciamos ‘miClase’

Ahora todos los objetos creados a partir de ‘miClase’ compartirán inicialmente las mismas referencias en todas sus propiedades, esto significa que, todos los objetos van a compartir la misma versión de ‘metodo’.

Adicionalmente, al utilizar la propiedad prototype, obtenemos otra ventaja, podemos usar la palabra reservada instanceof. Vemos como se usa si escribimos:alert(nuevoObjeto instanceof miClase) // muestra ‘true’

El problema del uso de prototype, es que todas las propiedades hacen referencia a las mismas del prototipo, por lo que si modificamos estos objetos se van a modificar también en todos los objetos creados con esta clase. En siguiente ejemplo cambiamos nuestra propiedad a un array para poder modificarla sin cambiar nuestra referencia, de modo que podamos ver lo que explico con un ejemplo:

/* creamos un constructor limpio */

miClase = new Function();

miClase.prototype.propiedad = new Array(“hola”,“hello”);

miClase.prototype.metodo = function(){

/* aqui ‘this’ hace referencia al objeto al que pertenece el metodo */

alert(this.propiedad);

}

nuevoObjeto = new miClase(); // instanciamos ‘miClase’

otroObjeto = new miClase(); // instanciamos ‘miClase’

nuevoObjeto.propiedad.push(“olá”);

otroObjeto.metodo(); // muestra “hola”,”hello”,”olá”

Como pueden ver en el ejemplo anterior, ‘nuevoObjeto’ y ‘otroObjeto’ hacen referencia al mismo array, para solucionar este problema solo debemos asignar un objeto diferente a cada propiedad de nuestros objetos. El constructor es un buen lugar para realizar esta tarea:

miClase = function(){

this.propiedad = new Array(“hola”,“hello”); // reemplazamos el valor de nuestra propiedad con un nuevo objeto

};

miClase.prototype.propiedad = new Array(“hola”,“hello”);

miClase.prototype.metodo = function(){

/* aqui ‘this’ hace referencia al objeto al que pertenece el metodo */

alert(this.propiedad);

}

nuevoObjeto = new miClase(); // instanciamos ‘miClase’

otroObjeto = new miClase(); // instanciamos ‘miClase’

nuevoObjeto.propiedad.push(“olá”);

otroObjeto.metodo(); // muestra “hola”,”hello” :)

Listo, tenemos clase y tenemos objetos que funcionan bien. Espero que les haya resultado claro, en el próximo post voy a explicar el mecanismo de la herencia en JavaScript (si!!, se puede!!). Hasta entonces.

About these ads

»

  1. Genial!! Enserio. Me ha servido para entender como funcionan las clases con prototype. Hasta ahora siempre las hacia de la manera normal, y creo que voy a seguir haciendolo. Porque eso de que se mezclen las propiedades y los metodos de todas las instancias…

    un saludo

    Responder
  2. gracias por tu comentario.
    Dentro de poco espero escribir un post sobre las librerias q existen para emular la sintaxis de los lenguajes como java. Por ahi eso te resulta mas familiar :)

    Responder
  3. yy cuando las henrencias

    Responder
  4. wow, la verdad muy util eso de emular clases, al igual que lo de prototype :D

    Responder
  5. ¿Es JavaScript un lenguaje orientado a objetos?
    Aporta con tu opinión en http://developer.mozilla.org/es/docs/Categor%C3%ADa:DSN_XP.JavaScript

    Saludos cordiales
    DSN

    Responder
  6. hola: bueno hoy tengo examen de javascript pues en internet dice que java,javascript es orientado a objetos mientras aki en la universidad nos dieron unos manuales y el las diapositivas del inginiero dice k java es un lenguaje orientado a objetos pero javascript no es orientado a objetos …

    Responder
  7. Hola Daniela,

    primero que nada, java no tiene nada que ver con javascript salvo el nombre, asi que trata de no relacionarlos.

    Por otro lado, como vos decis, javascript es un lenguaje orientado a objetos, ya que absolutamente todo en javascript es un objeto. Es decir, los datos como strings, las funciones, etc son objetos.

    Responder
    • Javascript es un lenguaje SCRIPT, BASADO en objetos, x eso como dices, todoo es un objeto. Sin embargo no soporta el paradigma POO tradicional por que se basa en PROTOTIPOS y NO en CLASES. sin mencionar que varias de las caracteristicas basicas de la POO no son admitidas en JS

      Responder
  8. Hello, muchas gracias por tu post me ha ayudado a entender como funcionan las clases con prototype.

    saludos.

    Responder
  9. Saludos,
    Buen Post,
    bueno aclarando sobre el tema de que si JS es poo, realmente no lo es, los programadores utilizan artificios para poder simular JS a poo, hablar de poo conyeba a tres aspectos basicos que tiene poo que son los siguientes:Abstracción,Encapsulamiento, herencia, polimorfismo; la cual js no cumple con todos los requisitos y para que no aya controvercia JS no tiene garbage collector. Bueno muchachos hasta otra oportunidad

    Responder
  10. Me estaba refiriendo a las funciones y a un ejemplo como este:

    miClase = function()
    {
    this.propiedad = “Hola”;
    this.metodo = function()
    {
    alert(this.propiedad);
    }
    }
    nuevoObjeto = new miClase(); //Instancia de miClase
    miClase.prototype.show = function(){alert(“123″);} //Uso de prototype.
    nuevoObjeto.metodo();
    nuevoObjeto.show();

    /****/
    var miClase2 =
    {
    propiedad: “Hola”,
    metodo: function()
    {
    alert(this.propiedad);
    }
    };
    var nuevoObjeto2 = miClase2;
    nuevoObjeto2.metodo();

    ¿Existe la posiblidad de usar la propiedad prototype, para miClase2?

    Responder
    • Si, en ambos casos se puede. Las dos diferentes formas de declaracion ( object = {} y object = new Object()) tienen el mismo resultado. Todos los objetos tienen la propiedad prototype.

      Responder
      • ok, pero como podría utilizar prototype en estos dos casos, tienes algún ejemplo?, muchas gracias de antemano.

  11. Gracias,, de verdad ha sido de mucha utilidad,, al fin algo claro de como utilizar los métodos en JavaScript.

    Responder
  12. Muy útil!

    Gracias!

    Responder
  13. Lo hice hace años y no recordaba cómo era la sintaxis. Me ha sido de gran utilidad! Muchas gracias!

    Responder
  14. Hoa, tengo una duda. Cuando uso new sin una varialbe previa… donde estoy construyendo el objeto?.

    Ejemplo:
    onload=function(){
    new ClaseX(‘log.txt’,function(r){document.getElementById(‘log’).innerHTML=r;});
    }

    Responder
  15. para un request las clases se usan de igual manera?

    Responder

Deja un comentario

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

%d personas les gusta esto: