JavaScript es un lenguaje de programación orientado a objetos basado en prototipos. Esto significa que en lugar de utilizar clases como en otros lenguajes, JavaScript utiliza prototipos como base para la herencia y la creación de objetos. En este artículo, exploraremos en detalle cómo funcionan los prototipos y la herencia en JavaScript, y cómo podemos utilizarlos para escribir código más eficiente y reutilizable.
En JavaScript, cada objeto tiene un enlace interno a otro objeto llamado "prototipo". Cuando accedemos a una propiedad de un objeto, si no se encuentra en el objeto en sí, JavaScript lo buscará en su prototipo. Si no se encuentra en el prototipo, se seguirá buscando en el prototipo del prototipo, y así sucesivamente. Este proceso se conoce como "búsqueda de prototipo" o "prototipado".
La forma más común de crear un objeto en JavaScript es utilizando la sintaxis de objeto literal. Por ejemplo:
const obj = {
propiedad: valor
};
Cuando accedemos a una propiedad de obj
, JavaScript buscará primero la propiedad en el objeto en sí. Si no se encuentra, buscará en el prototipo del objeto, que es Object.prototype
en este caso.
En JavaScript, también podemos utilizar funciones constructoras para crear objetos. Una función constructora es una función que se utiliza para inicializar un objeto. Podemos definir propiedades y métodos en el prototipo de la función constructora, y estos estarán disponibles en todos los objetos creados a partir de ella.
function Persona(nombre, edad) {
this.nombre = nombre;
this.edad = edad;
}
Persona.prototype.saludar = function() {
console.log(`Hola, mi nombre es ${this.nombre} y tengo ${this.edad} años.`);
};
const persona1 = new Persona('Juan', 30);
persona1.saludar(); // Hola, mi nombre es Juan y tengo 30 años.
En el ejemplo anterior, creamos una función constructora Persona
que tiene dos parámetros: nombre
y edad
. Dentro de la función, asignamos estos valores a las propiedades nombre
y edad
del objeto actual utilizando la palabra clave this
. Luego, agregamos un método saludar
al prototipo de Persona
, el cual imprimirá un mensaje utilizando las propiedades del objeto actual.
Cuando creamos un objeto utilizando la palabra clave new
, JavaScript crea un nuevo objeto vacío y establece el prototipo de ese objeto en el prototipo de la función constructora. Luego, ejecuta la función constructora con this
apuntando a ese nuevo objeto. Finalmente, devuelve el objeto creado.
En JavaScript, la herencia se logra a través de la cadena de prototipos. Podemos establecer la relación de herencia entre dos funciones constructoras utilizando el método Object.create()
. Veamos un ejemplo:
function Animal(nombre) {
this.nombre = nombre;
}
Animal.prototype.saludar = function() {
console.log(`Hola, soy un ${this.nombre}.`);
};
function Perro(nombre, raza) {
Animal.call(this, nombre);
this.raza = raza;
}
Perro.prototype = Object.create(Animal.prototype);
Perro.prototype.constructor = Perro;
Perro.prototype.ladrar = function() {
console.log('¡Guau, guau!');
};
const miPerro = new Perro('Max', 'Labrador');
miPerro.saludar(); // Hola, soy un Max.
miPerro.ladrar(); // ¡Guau, guau!
En este ejemplo, creamos una función constructora Animal
que tiene una propiedad nombre
y un método saludar
. Luego, creamos una función constructora Perro
que hereda de Animal
utilizando Object.create()
. Esto establece el prototipo de Perro
como Animal.prototype
, lo que permite que los objetos creados a partir de Perro
accedan a las propiedades y métodos de Animal
.
Note que utilizamos Animal.call(this, nombre)
dentro de Perro
para llamar a la función constructora Animal
con el objeto this
actual y el parámetro nombre
. De esta manera, podemos inicializar la propiedad nombre
en el objeto Perro
.
También es importante mencionar que restablecemos el constructor de Perro
después de establecer su prototipo. Esto se debe a que al establecer el prototipo de Perro
en Animal.prototype
, el constructor se establece automáticamente en Animal
. Al restablecer el constructor, aseguramos que Perro.prototype.constructor
se refiere a Perro
en lugar de Animal
.
En este artículo, hemos explorado los conceptos de prototipos y herencia en JavaScript. Hemos visto cómo utilizar funciones constructoras y prototipos para crear objetos y cómo establecer relaciones de herencia entre ellos. El uso de prototipos y herencia en JavaScript puede ayudarnos a escribir código más eficiente y reutilizable, permitiendo la creación de objetos con propiedades y métodos compartidos.
Para profundizar en estos temas, te recomiendo consultar las siguientes referencias: