Blog
JavaScript – Herencia
- Publicado por: Rafael Fernandez
- Categoría: Nivel Medio Javascript
En JavaScript los objetos heredan características entre sí mediante un mecanismo conocido como prototipos.
Durante este módulo del curso, explicaremos en que consiste una cadena de prototipos y como se puede usar para añadir métodos a los constructores previamente establecidos.
Cadena de prototipos
En JavaScript cada objeto posee un objeto prototipo que se comporta como una plantilla, con el cual es capaz de heredar propiedades y métodos.
Ahora bien, dicho objeto prototipo a su vez puede tener un objeto prototipo que hereda propiedades y métodos y así sucesivamente formando lo que se conoce como cadena de prototipos.
Cabe resaltar que las propiedades y métodos son definidos en la propiedad prototipo dentro de las funciones del constructor y no en las instancias de los objetos.
Veamos un ejemplo:
Function ejemploPrototipo( ) { } console.log( ejemploPrototipo.prototype); var ejemploPrototipo = function( ) { }; console.log( ejemploPrototipo.prototype);
Indiferentemente de cómo se declare una función, esta siempre contara con una propiedad prototype predeterminada.
Así se demuestra en la consola, donde debe aparecer lo siguiente después de ejecutar el código:
{ constructor: ƒ ejemploPrototipo(), __proto__: { constructor: ƒ Object(), hasOwnProperty: ƒ hasOwnProperty(), isPrototypeOf: ƒ isPrototypeOf(), propertyIsEnumerable: ƒ propertyIsEnumerable(), toLocaleString: ƒ toLocaleString(), toString: ƒ toString(), valueOf: ƒ valueOf() } }
Por otro lado, si queremos añadir propiedades al prototipo previamente establecido debemos escribir:
Function ejemploPrototipo( ) { } ejemploPrototipo.prototype.foo = “abc”; console.log(ejemploPrototipo.protoype);
Luego de correr el código aparecerá en pantalla:
{ foo: "abc", constructor: ƒ ejemploPrototipo(), __proto__: { constructor: ƒ Object(), hasOwnProperty: ƒ hasOwnProperty(), isPrototypeOf: ƒ isPrototypeOf(), propertyIsEnumerable: ƒ propertyIsEnumerable(), toLocaleString: ƒ toLocaleString(), toString: ƒ toString(), valueOf: ƒ valueOf() } }
En este punto podemos crear una instancia utilizando el operador “new”.
Para ello se debe llamar a la función como lo hemos hecho hasta ahora, pero incluyendo el prefijo “new”.
Esto hará que retorne un objeto y dicho objeto será la instancia de la función.
function ejemploPrototipo( ) { } ejemploPrototipo.prototype.foo = "abc"; // esta línea añade una propiedad al prototipo var instanciaEjemploPrototipo= new ejemploPrototipo(); instanciaEjemploPrototipo.prop = "valor"; // esta línea añade una propiedad al objeto console.log( instanciaEjemploPrototipo );
El resultado será:
{ prop: "valor", __proto__: { foo: "abc", constructor: ƒ ejemploPrototipo(), __proto__: { constructor: ƒ Object(), hasOwnProperty: ƒ hasOwnProperty(), isPrototypeOf: ƒ isPrototypeOf(), propertyIsEnumerable: ƒ propertyIsEnumerable(), toLocaleString: ƒ toLocaleString(), toString: ƒ toString(), valueOf: ƒ valueOf() } } }
Entendamos lo que acabamos de hacer.
En primer lugar, hemos de acotar que el prototipo de “instanciaEjemploPrototipo” es “ejemploPrototipo”.
Este prototipo hace que a la hora de acceder a una propiedad “instanciaEjemploPrototipo”, el navegador web revise si existe dicha propiedad, de lo contrario lo buscará entre las propiedades del prototipo.
Por consiguiente, si el navegador encuentra la propiedad entonces la propiedad de “instanciaEjemploPrototipo” puedeutilizarse.
No obstante, en caso de no encontrarla allí buscará en el prototipo del prototipo de “instanciaEjemploPrototipo” y así sucesivamente hasta encontrarla o en su defecto mostrar un mensaje que indique que no existe y concluir que el valor de la propiedad es “undefined”.
Cadenas de prototipos usando un constructor
Recordemos que un constructor no es más que una función que se invoca mediante el operador new. Como lo vemos a continuación:
function Grafico() { this.vertices = []; this.bordes = []; } Grafico.prototype = { addVert: function(v){ this.vertices.push(v); } }; var obj = new Grafico(); }
En este ejemplo el objeto “obj” posee las propiedades “vértices” y “bordes”.
Y obj.[[Prototype]] es el valor de Grafico.prototype cuando el constructor es ejecutado.