La programación orientada a objetos (POO) es un paradigma de programación que se enfoca en el uso de objetos para representar conceptos del mundo real y manipular datos. JavaScript es un lenguaje orientado a objetos basado en prototipos, lo que significa que los objetos en JavaScript tienen una relación de prototipo entre ellos, en lugar de tener una relación de clase como en lenguajes como Java o C#.
Una de las principales diferencias entre JavaScript y otros lenguajes orientados a objetos es el uso de clases en lugar de prototipos. Aunque JavaScript no tiene una sintaxis específica para definir clases, a partir de ECMAScript 6 se pueden utilizar las palabras clave "class" y "extends" para simular una estructura de clase. Sin embargo, debajo de esta sintaxis se sigue utilizando prototipos para la herencia. Por ejemplo:
Como habrás visto, en este pequeño ejemplo hay muchas keywords nuevas como: new, this, extends, constructor. Posiblemente sea tu primer acercamiento a estos conceptos, por lo que es momento de entender cada uno de estos.
Empecemos por this , this se refiere al objeto actual en el cual se está ejecutando un método o accediendo a una propiedad. En una función constructora, thisse refiere al nuevo objeto que se está creando. Por ejemplo:
functionAnimal(especie){// Función constructorathis.especie= especie;}Animal.prototype.respirar=function(){// En este scope no existe "especie"// Pero con "this" estamos accediendo directamente a "Animal"// Por lo que esto vendría siendo "Animal.especie"console.log(`La especie ${this.especie} está respirando...`);}const perro =newAnimal("Canino");perro.respirar();// Output: "La especie Canino está respirando..."
Este ejemplo es muy parecido al anterior, básicamente es lo que hace JavaScript para convertir las clases en prototipos, si bien ahora existen las clases como lo viste al principio de esta lectura, debes de comprender como funciona el lenguaje por debajo sin toda esa sugar syntax.
Con clases, esto se vería mejor 👇
// TODAS las clases empizan por mayúscula por convenciónclassAnimal{constructor(especie){// Con clases la función constructora es más explicita, aquí se asignan// los valores recibidos// Parecido a las funciones, se recibe como parametro cualquier valor necesario// y lo pasamos al scope de la clase con "this.valor = valor"this.especie= especie
}respirar(){// Directamente podemos crear los métodos dentro de las clases// básicamente una función cualquier pero sin la keyword "function"console.log(`La especie ${this.especie} está respirando...`)}}const perro =newAnimal("Canino");perro.respirar();// Output: "La especie Canino está respirando..."
Pero ambas practicas, vienen siendo igual a lo que modifica el prototype.
Ahora, cuando estamos declarando la variable perro usamos la keyword new que se usa para crear una nueva instancia de una función constructora. Cuando se usa new con una función constructora, se crea un nuevo objeto, se establece su prototipo y se ejecuta el código dentro de la función constructora con this apuntando al nuevo objeto. Por ejemplo:
// Aquí estamos creando una copia de la clase Animal o mejor dicho creando una instancia// Por lo que perro, es una instancia de Animal que tiene como especie el valor de "Canino"const perro =newAnimal("Canino");// De esta manera podemos acceder a todos los métodos creados en la claseperro.respirar();// Output: "La especie Canino está respirando..."
Solo falta conocer un concepto nuevo, extends
classPerroextendsAnimal{// Aquí no es necesario el agregar el constructor si no se esperan// nuevos parametrosladrar(){console.log("Guau!");}}
Esto se le conoce como una subclase, que se refiere a una clase que hereda de otra clase.
La keyword extends nos ayuda a copiar todo de la clase que extiende a la nueva clase y así evitar ser redundante y tener una buena jerarquía. Por lo que anterior viene siendo igual a lo siguiente
Object.create() que se usa para crear un nuevo objeto con un prototipo específico. Este método recibe un objeto como primer parámetro y devuelve un nuevo objeto con ese objeto como su prototipo.
Te invito a que ejecutes este código en la consola de tu navegador y veas hasta a que lugar te lleva el prototype de los objetos 😉