En este capítulo comenzaremos a hablar sobre una de las cosas más importantes en Javascript, y son los prototipos. Javascript es un lenguaje multiparadigma, es decir, podemos utilizar diferentes paradigmas de programación (programación funcional, programación orientada a objetos..). A día de hoy el paradigma más utilizado en la mayoría de lenguajes de programación es el de la programación orientada a objetos o POO, y una característica muy importante de Javascript es que la orientación a objetos en el lenguaje es muy diferente a otros lenguajes basados en clases como C, Java…
A partir del estándar ES6 ya tenemos clases, sin embargo dichas clases no son más que un azúcar sintáctico, es decir, una manera más fácil que provee Javascript para poder hacer la programación basada en prototipos, es decir, aunque ya tenemos clases en Javascript, esas clases, el compilador del navegador las convierte a funciones prototípicas. Por lo tanto es muy importante entender lo que son los prototipos en Javascript.
Conceptos de la POO
Dentro de la POO (programación orientada a objetos) hay 4 conceptos muy importantes que debemos entender:
- Clases: son modelos a seguir, es decir, algo que sirve como esquema para de ahí basarnos y poder generar instancias.
- Objetos: es una instancia de una clase, es decir, una copia de ese modelo.
- Atributos: son características o propiedades del objeto. Son variables dentro de un objeto.
- Métodos: son las acciones que un objeto puede realizar, son funciones dentro de un objeto.
Prototipo en Javascript
Un prototipo es un mecanismo por el cual un objeto puede heredar de un objeto padre atributos y métodos. De hecho la herencia en Javascript se da mediante la cadena de prototipos. Por decirlo, crea una copia del prototipo en el cual está basado.
Vamos a crear un ejm generando un prototipo del cual nos basemos para hacer copias del mismo. Vamos a crear lo que se denomina una función constructora, que, como su nombre dice, la vamos a construir una sola vez y a partir de ella vamos a generar nuevas instancias (nuevos objetos) que sean de este tipo de función constructora.
Ejm
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Prototipos en Javascript</title> </head> <body> <h1>Prototipos en Javascript</h1> <script> function Persona(nombre, genero) { this.nombre = nombre; this.genero = genero; this.hablar = function () { console.log("Estoy hablando pq soy una persona"); }; } const francisco = new Persona("Francisco", "Macho"), beatriz = new Persona("Beatriz", "Hembra"); console.log(francisco.nombre); console.log(beatriz.nombre); </script> </body> </html>
Si vamos a necesitar varias instancias del mismo tipo que estemos creando, en vez de crear varias funciones con el mismo código repetido, lo que conviene más es hacer una función constructora.
Por lo que podemos ver, la función hablar() la podemos en vez de cargarla en todas las instancias, cargarla solo de manera única cuando la necesitemos. Lo suyo sería asignar al prototipo de la función Persona() el método hablar(), es decir, sacarlo de la función prototípica y asociarlo a la misma fuera de ella, ya que al tenerlo dentro de la misma, cada vez que generamos una instancia de nuestra función prototípica, se está duplicando este método hablar(), y si tuviéramos más métodos, se estarían duplicando en todas las instancias, consumiendo memoria. Lo ideal es que nuestras funciones constructoras sólo tengan los atributos, y los métodos los saquemos de nuestra función constructora y se los peguemos al prototipo de la siguiente forma.
Ejm
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Prototipos en Javascript</title> </head> <body> <h1>Prototipos en Javascript</h1> <script> function Persona(nombre, genero) { this.nombre = nombre; this.genero = genero; } // Métodos agregados al prototipo de la función constructora Persona.prototype.hablar = function () { console.log(`Hola, mi nombre es ${this.nombre}`); }; const francisco = new Persona("Francisco", "Macho"); console.log(francisco); francisco.hablar(); </script> </body> </html>