Estamos de regreso con nuestro programa para crear "Winstons"
pero añadí un nuevo tipo de objeto "Hooper" porque "Hooper" se sentía un poco solo.
Ahora, defino a "Hooper" de la misma manera que definí a "Winston", ya sabes,
empezando con la función constructora y tomando las mismas propiedades y luego "draw" (dibujar)
y luego "talk" (hablar), y luego también añadí otro método
llamado "Horray" porque a los "Hoppers" realmente le gusta celebrar y a los "Winstons" en realidad no.
Ahora, al final de la función he creado
dos nuevos objetos "Hooper": "Little Hopper" y "Big Hooper",
los dibujo y en uno llamo la función "talk" y en el otro "Horray".
Eso está muy bien.
Ahora, si miramos este código que está aquí arriba
te darás cuenta de algo interesante.
Y es que el código para "Hooper" es muy similar al código para "Winston". Particularmente el constructor.
No se si recuerdes pero básicamente es el mismo código que nuestra función constructora de"Winston".
Y luego en esta función "talk" el código es exactamente el mismo que en la función "talk" de "Winston",
y ambos tienen funciones "draw",
así que tienen muchas cosas en común en estos dos tipos de objetos,
y eso tiene sentido porque ya sabes "Hooper" y "Winston" son dos tipos de objetos muy similares
en nuestro mundo. Si piensas en eso, ya sabes, en el mundo real
fuera de la computadora, muchos tipos de objetos tienen semejanzas
con otros tipos de objetos.
Como en el reino animal. Todos los animales son similares de alguna forma.
Y luego tenemos diferentes tipos de animales como los humanos.
Y los humanos comparten esas similitudes
pero también tiene sus propias similitudes únicas.
Así que podríamos decir que
un animal es un tipo de objeto del que el tipo de objeto humano hereda funcionalidad.
No iniciamos completamente de cero sino que agregamos a la funcionalidad que ya tenemos de ser un animal.
Como que todos los animales hacen ruidos,
pero los humanos también tienen lenguaje.
Así que este concepto de herencia de objetos
en realidad también es muy útil en programación.
Y podemos crear una cadena de herencia de objetos en nuestro Javascript.
Así que para hacer esto cuando piensas
qué es lo que comparten nuestros tipos de objetos,
y tienes un nombre para ello,
porque vamos a crear un tipo de objeto
que representa el objeto base
así que vamos a llamarle "Creatures" (criaturas). Ambos son criaturas.
Así que decimos "var Creature = ". Y ahora necesitamos nuestra función constructora.
Así que solamente vamos y copiemos la de "Hopper" para que tenga lo mismo que "Winston" tiene.
Muy bien.
Y luego, vamos a ver.
Ahora queremos,
¿Qué es lo que queremos ahora?
Tal vez queremos añadirle la función "talk".
Así que para la función "talk", sólo la copiamos de "Hooper". Pero por supuesto necesitamos que diga "Creature.prototype" en lugar de esto.
Ok, genial.
Así que ahora tenemos este tipo de objeto "Creature".
Pero en realidad necesitamos decirle a "Hooper" que
"Hooper" debe basar su funcionalidad en "Creature".
Así que podemos hacer eso escribiendo esta línea aquí.
Decimos "Hopper.prototype = Object.create"
"(Creature.prototype);"
Entonces, lo que hace esta línea es decirle a Javascript que base el prototipo de "Hopper", es decir,
toda la funcionalidad de "Hopper" en el prototipo de "Creature".
Y entonces esto significa que cada vez que busque una función en "Hooper" buscará primero en el prototipo de "Hooper"
pero si no lo encuentra lo buscará en el prototipo de "Creature".
Y esto es a lo que llamamos cadena de prototipos.
Ahora una vez que hemos hecho esto deberíamos poder borrar la función "talk".
En "Hooper".
Porque ya existe en "Creature".
Que está más arriba en la cadena de prototipos.
¿Listo? ¡Tan tan tan!
¡Funcionó!
Y funcionó porque encuentra la función en el prototipo de "Creature".
Mmm. Así que tratemos de borrarla de "Winston" también.
Ok. No funcionó, nos dice que el objeto no tiene método "talk".
¿Y por qué es eso? Bueno, tenemos nuestro constructor de "Winston",
y "draw" y borramos la función "talk".
Bueno, notarás que en realidad olvidamos decirle que el prototipo de "Winston" debe estar basado
en el prototipo de "Creature".
Así que necesitamos esa línea tan importante.
"Winston.prototype = Object.create"
"(Creature.prototype);"
¡Tan tan!
Y fíjense en algo importante.
Tengo esta línea después de la función constructora pero antes de añadir cualquier cosa
al prototipo de "Winston".
Eso es lo que generalmente quieres hacer.
Quieres decírselo inmediatamente cuando empiezas
en esto se basa tu prototipo inicial.
Pero luego seguimos añadiendo más cosas al prototipo.
Porque habrá alguna cosa que es única a los "Winstons" o única a los "Hoopers"
que no tiene los "Creatures".
Y es genial que puedas definir esas cosas.
Muy bien. Ahora, si miramos esto, todavía tenemos código repetido.
El código constructor.
¿Cierto? Tenemos todo esto tres veces.
¿Podríamos simplemente borrarlo?
Tratemos.
Ok, mmm. No parece haber funcionado.
Porque nuestro "Hooper" aparece en la esquina superior izquierda, parece que olvidó todo sobre él.
Y esto es porque Javascript no asume que quieres el mismo constructor incluso si quieres basar el prototipo en él.
Ya sabes, te permite definir tu propio constructor para esos objetos.
Pero también te da una forma fácil de llamar al constructor de un objeto.
Así que la forma en que haremos esto es
escribiendo "Creature.call(this, nickname, age, x, y);"
Ahora, lo que esto hace (Nota que funcionó. Sí), lo que hizo es
que en realidad está llamando a la función "Creature", la función constructora.
Está llamando esa función pero está pasando y está diciendo: "ok, debes llamar la función constructora como
si la estuviera llamando este objeto 'Hooper'
y como si la estuviera llamando con estos argumentos".
Estos son argumentos con los que se llamó "Hooper".
Y terminará ejecutando este código como si estuviera justo aquí.
Y es exactamente lo que queremos. Y funcionó.
Y podemos continuar y
copiar esta línea en la función constructora
de "Winston" también.
Y funcionó. ¡Sí!
Muy bien. Revisemos esto. Hemos encapsulado todas nuestras propiedades compartidas y funcionalidades
en este tipo de objeto base, "Creature".
Y hemos hecho dos tipos de objeto que provienen de este tipo de objeto base.
Ellos heredan la funcionalidad pero añaden la suya propia también.
Y lo interesante de esto es que podemos cambiar la funcionalidad compartida en un sólo lugar.
Como si quisiéramos cambiar la edad de nuevo, podríamos decir más "years old" (años de edad).
Ahora todos tienen "years old" al final.
O podríamos cambiar la función "talk" y poner "SUPPP!?!?!?!?". Y ahora los "Winstons" y los "Hoopers" dirán "SUP".
Entonces, ahora has visto como crear tipos de objetos y heredar de los tipos de objetos,
puedes empezar a pensar cómo sería útil esto en tus dibujos, animaciones, simulaciones y juegos.
Por ejemplo, tal vez tienes un juego y tienes muchos tipos de personajes en él,
y todos ellos pueden correr pero sólo algunos de ellos pueden saltar.
Ese es un lugar perfecto para usar algunos tipos de objetos y algo de herencia.
Pero apuesto a que puedes pensar en muchas más formas de hacerlo.