Entendiendo la herencia prototípica de JavaScript

La herencia

La herencia es el proceso por el cual un objeto puede basarse en otro. Esto permite que los objetos compartan sus propiedades.

He creado el prototipo Hero y lo he utilizado para crear un nuevo objeto llamado superman. Pero no estamos haciendo nada con este objeto. Así que vamos a ocuparnos de eso creando otra función llamada dialogue.

function dialogue() {
console.log('I am ' + this.name);
}

Pero si ejecutamos nuestro código ahora, no va a pasar nada porque esta función no sabe cuál es el nombre realmente. Para ello, necesitamos

Quiero que esta nueva función tenga las mismas propiedades que la Hero. En lugar de escribirlas dentro de esta función, podemos simplemente decirle a JavaScript que las herede del prototipo Hero.

Esto es posible con la ayuda de la propiedad prototype que está disponible dentro de cualquier objeto en JavaScript.

Al colocar dialogue en Hero.prototype, hemos hecho que esté disponible para todas las instancias de Hero.

Herencia diferencial

JavaScript también viene con otro modelo de herencia llamado «herencia diferencial». En este modelo, los métodos no se copian del padre al hijo. Pero en su lugar hay un vínculo entre los hijos y su objeto padre.

Aquí, superman no tiene realmente su propio método llamado dialogue(). Pero entonces, ¿cómo funciona superman.dialogue()?

Cuando el motor de JavaScript se encuentra con superman.dialogue() en el código, busca la propiedad llamada dialogue dentro del objeto superman. Si no la encuentra, buscará en la cadena de prototipos al padre superman, Hero.prototype. Allí encontrará Hero.prototype.dialogue y lo llamará con un this que está ligado a superman.

Object.create()

Podemos hacer esto aún más exclusivo creando una nueva clase para Superman que heredará las propiedades del prototipo Hero. Podemos hacer esto asignando el prototipo de al prototipo de Hero así:

function Superman() {}
Superman.prototype = Hero.prototype

Pero lo que hace esto es que simplemente hace que tanto como Hero sean iguales. Lo que realmente necesitamos es un nuevo objeto que se base en el prototipo Hero. Desde ES5, JavaScript viene con una función incorporada llamada Object.create(). Usémosla aquí como se muestra a continuación:

Superman.prototype = Object.create(Hero.prototype);

Esto creará un nuevo objeto vacío que está basado en el prototipo Hero y lo asignará al prototipo Superman. Así que todas las propiedades que tenemos en el prototipo Hero pueden ahora ser accedidas por el prototipo Superman. Así que en lugar de llamar a new Hero, podemos llamar a new Superman y todo seguirá funcionando como debería.

Pero si te fijas bien en la salida, te darás cuenta de que hay un undefined dentro de ella. Eso es porque actualmente el Hero es un constructor sólo para sí mismo. Tenemos que call las propiedades de Hero dentro del prototipo Superman.

function Superman() {
Hero.call(this, 'Superman', 'Clark Kent', 'Krypton')
}

Creemos otro constructor llamado MarvelMovies como se muestra a continuación:

function MarvelMovies(movieName, releaseYear) {
this.movieName = movieName;
this.releaseYear = releaseYear;
}

Cuando se utiliza una función como constructor, this se refiere al nuevo objeto que estamos creando. Así que en este constructor, he tomado movieName y releaseYear como argumentos y he asignado esos valores a las propiedades movieName y releaseYear de nuestra nueva instancia MarvelMovies llamada avengers.

var avengers = new MarvelMovies("avengers", 2012);

A continuación voy a crear un nuevo método llamado output para este prototipo como se muestra a continuación:

MarvelMovies.prototype.output = function() {
return "Movie: " + this.movieName + " Released in " + this.releaseYear;
}
console.log(avengers.output());

Futura herencia

Un aspecto realmente bueno de la herencia es que JavaScript te permite modificar o ampliar las características de una clase incluso después de haberla definido.

JavaScript buscará el prototipo cuando intente acceder a las propiedades de un objeto. Para ilustrar esto, vamos a crear un array como se muestra a continuación:

var numbers = ;
Array.prototype.shuffle = function() {
return this.sort(function() {
return Math.round( Math.random() * 2) - 1;
});
};
console.log(numbers.shuffle());

Aquí, el array numbers existía antes que el Array.prototype.shuffle. Pero en JavaScript, las búsquedas de propiedades suben por la cadena de prototipos. Esta es la razón por la que el array sigue teniendo acceso al nuevo método shuffle, ya que existe en el Array.prototype cuando realmente estamos tratando de usarlo.

En términos simples, creamos un array, luego volvimos y dimos a todos los Arrays acceso a un nuevo método.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.