JavaScript 00: 4. Object.create

En esta entrada aprenderemos cómo crear objetos mediante la propiedad Object.create.

waterhouse

archivado en: JavaScript / 17 Junio, 2013 / taller:

En un lenguaje orientado a objetos las piezas fundamentales, los átomos de la aplicación, son las clases, en las que se encapsulan una serie de propiedades (variables) y métodos (funciones). Para trabajar con las clases se declaran «instancias», que son como copias particulares de las mismas.

class unaClase

{

propiedadColor = rojo;

function métodoPintar() {

pintar pared;

}

}

unaInstancia = new unaClase;

ejecuta unaInstancia->métodoPintar de color propiedadColor.

En JavaScript, como hemos visto, todo gira en torno a los objetos, que en cierta manera se pueden comparar con las clases, en tanto que son colecciones de métodos y propiedades. Las principales maneras de declarar un objeto son las siguientes:

1) Mediante una función constructora

Es la que he hemos visto en las entradas anteriores. Se asigna una función a una variable, que se convierte en un objeto, a la cual se le pueden pasar parámetros para inicializar el objeto. De ahí el apelativo de «constructora», por analogía con la poo normal, en la que las clases suelen tener un método especial denominado constructor que sirve para inicializar la clase. (En realidad, se puede definir directamente la función sin pasar por la variable, pero creo que es mejor así por razones que explicaré otro día).

Entre otras cosas, este tipo de objetos se caracterizan porque se pueden encapsular sus métodos y propiedades anteponiendo la palabra this. También es característico que para invocarlos antes hay que asociarlos a una instancia mediante el operador new.

var calculadora = function(recogeA, recogeB) {

this.a = recogeA;

this.b = recogeB;

this.sumar = function() {

return this.a+this.b;

}

}

instanciaCalculadora = new calculadora(5, 10);

console.log(instanciaCalculadora.sumar()); // 15

En este caso podemos agregar métodos y propiedades al objeto original mediante la propiedad prototype.

calculadora.prototype.restar = function() {

return this.a-this.b;

}

instanciaCalculadora = new calculadora(5, 10);

console.log(instanciaCalculadora.restar()); // -5

De hecho, es recomendable que el objeto original solo tenga definidas las propiedades y los métodos, en cambio, vayan prototipados, pues así solo se crean una vez por instancia, tal y como veremos en la próxima entrada.

2. Mediante notación de literales

Otra forma es declarando métodos y propiedades como si fuera un array de elementos (que pueden a su vez contener otros elementos) separados por comas. Para acceder a las cosas se utiliza la notación de puntos.

var calculadora = {

a: 5,

b: 10,

sumar: function() {

return calculadora.a+calculadora.b;

}

}

console.log(calculadora.sumar()); //15

3. Instanciando el objeto Object

Otra manera, un tanto bruta, es sacando una instancia del objeto Object, a la cual le añadimos las propiedades y métodos directamente.

var calculadora = new Object();

calculadora.a = 5;

calculadora.b = 10;

calculadora.sumar = function() {

return calculadora.a + calculadora.b;

}

calculadora.restar = function() {

return calculadora.a - calculadora.b;

}

console.log(calculadora.sumar()); // 15

console.log(calculadora.restar()); // -5

4. Con Object.create

Esta fórmula se incorporó en la versión 1.8.5 de JavaScript (julio de 2010), por lo que no funciona en las versiones antiguas de la tostadora del Explorer (del 8 para abajo), pero como veremos cuando hablemos de herencia es la más potente cuando tenemos un proyecto grande y, en cualquier caso, se pueden hacer apaños para esta pesadilla de navegador.

La sintaxis básica es la siguiente: se declara una variable objeto y se inicializa definiendo el objeto que está prototipando (la propiedad proto que vimos en la entrada anterior) y, opcionalmente, sus propiedades.

var miObjeto = Object.create(proto [, propertiesObject ]);

Si el objeto no es un prototipo de uno que ya hemos creado, en el parámetro proto podemos poner null u Object.prototype, que para el caso es lo mismo, aunque no son equivalentes. Por ejemplo, así primero creamos un objeto «de nuevas» llamado animal y luego otro prototipado de aquel llamado gato.

var animal = Object.create(null);

var gato = Object.create(gato);

Por decirlo de alguna manera, es como si gato fuera una copia de animal, es decir, que participa de todos los métodos y propiedades que tiene su objeto-padre.

Hay muchas maneras de definir las propiedades de este tipo de objetos. Una es, como decía, en la propia declaración del objeto.

var animal = Object.create(null, {

comer: {

value: "ñam, ñam"

},

dormir: {

value: "zzzzz..."

}

});

var gato = Object.create(animal);

console.dir(gato.dormir); // zzzzz...

Otra es mediante el método Object.defineProperty, en la que se definen el objeto al que está referida (añadida), el nombre y los descriptores, que luego veremos qué son.

Object.defineProperty(obj, prop, descriptores);

En el ejemplo que expuse antes:

var animal = Object.create(null);

Object.defineProperty(

animal,

"dormir", //<-------- Obsérvese que va entre comillas!

{ value: "zzzz..." }

);

console.log(animal.dormir); // zzzz..

Para definir métodos la fórmula es similar:

var gato = Object.create(animal, {

ronronear: {

value: function() {

return "...rrrrr...";

}

}

}

);

console.log(gato.ronronear()); // ...rrrrr...

¿Todo claro hasta aquí? Bueno, pues vamos a ver qué es eso de las propiedades-descriptoras.

Ya sea declarando las propiedades cuando definimos el objeto con Object.create, ya sea cuando las añadimos con Object.defineProperty, podemos especificar 4 cosas que se conocen como propiedades-descriptoras o propiedades-atributo y son:

  1. value: el valor de la propiedad. Puede ser cualquier valor habitual de una variable (una cadena de texto, un número, un valor booleano, una función...). Por defecto es undefined.
  2. writable: («escribible»). Un valor booleano que indica si se puede (true) o no (false) modificar. Por defecto es false.
  3. enumerable: si debe mostrarse (true) o no (false) en una enumeración for... in. Por defecto es false.
  4. configurable: si se puede (true) o no (false) modificar de alguna manera, por ejemplo, borrándola o cambiando los valores de las demás propiedades descriptoras. Por defecto es false.

var animal = Object.create(null);

Object.defineProperty(

animal,

"dormir",

{ value: "zzzz...",

writable: true,

enumerable: true,

configurable: true }

);

Object.defineProperty(

animal,

"comer",

{ value: "ñam, ñam",

writable: false,

enumerable: false,

configurable: false }

);

animal.dormir = "grunf, grunf";

animal.comer = "grunf, grunf";

console.log(animal.dormir); // grunf, grunf

console.log(animal.comer); // ñam, ñam

for (var i in animal) {

console.log(i); // dormir

}

delete animal.dormir;

console.log(animal.dormir) // undefined

delete animal.comer;

console.log(animal.comer) // ñam, ñam

(He separado la definición de propiedades por razones didácticas, pero se podrían haber declarado conjuntamente con Object.defineproperties).

Hay otras dos, get y set, pero las vemos por encima, pues volveremos sobre ellas con detalle cuando hable de la herencia. Get sirve para leer una propiedad y set para cambiar su valor. Vamos a dejarlo de momento aquí.

|| Tags: , ,

valoración de los lectores sobre JavaScript 00: 4. Object.create

  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • 4.8 sobre 5 (11 votos)

¿Te ha parecido útil o interesante esta entrada?
dormido, valoración 1 nadapensativo, valoración 2 un poco sonrisa, valoración 3 a medias guiño, valoración 4 bastante aplauso, valoración 5 mucho

Tú opinión es muy importante, gracias por compartirla!

Una respuesta a “JavaScript 00: 4. Object.create

  1. Te explicas muy bien Marcos, y mola ese toque de humor que le das a los ejemplos, así es más ameno seguir leyendote.

Aportar un comentario

*