Cuando trabajas con clases e instancias en JavaScript, tarde o temprano necesitarás agregar métodos nuevos que no existían en la clase original. Entender dónde y cómo se agregan esos métodos marca la diferencia entre un código que funciona y uno que falla silenciosamente. Aquí se explica el mecanismo de prototype, la cadena de prototipos y los errores más frecuentes al manipular instancias.
¿Cómo se agrega un método nuevo a una instancia?
Imaginemos que ya tenemos una clase Perro con sus métodos correr y emitirSonido, y creamos una instancia llamada perro1. Si durante el desarrollo detectamos que necesitamos un comportamiento extra, podríamos intentar algo como esto [0:06]:
javascript
perro1.nuevoMetodo = function () {
console.log("Este es un nuevo método");
};
Al inspeccionar perro1, el método aparece y funciona correctamente. Sin embargo, este método solo existe en esa instancia específica. Si creamos otra instancia de Perro, no tendrá acceso a nuevoMetodo porque nunca se agregó a la clase constructora.
¿Por qué la clase constructora no refleja el método?
Al revisar la clase Perro directamente, solo aparecen los métodos definidos originalmente: correr y emitirSonido. El método agregado vive únicamente en el objeto perro1 [1:10]. Esto ocurre porque agregar propiedades a una instancia no modifica la clase padre ni su prototype.
¿Qué es el prototype y por qué importa?
El prototype es un objeto especial que JavaScript crea automáticamente junto con cada clase o función constructora. Contiene los métodos que pueden ser compartidos y heredados por todas las instancias. Las instancias, en cambio, no poseen un prototype propio. Si ejecutamos perro1.prototype, el resultado es undefined [3:28]. Pero al consultar Perro.prototype, obtenemos el objeto con los métodos disponibles para heredar.
¿Cuál es la forma correcta de inyectar métodos al prototype?
Para que todas las instancias accedan a un método nuevo, debemos agregarlo al prototype de la clase constructora, no al de la instancia [2:15]:
javascript
Perro.prototype.segundoMetodo = function () {
console.log("Es otro nuevo método");
};
Después de esta línea, cualquier instancia —incluyendo las que ya existían— puede llamar a segundoMetodo. Al ejecutar perro1.segundoMetodo(), el mensaje se imprime correctamente [4:12].
- Agregar métodos a una instancia los limita a esa instancia.
- Agregar métodos al prototype de la clase los comparte con todas las instancias.
- Las instancias no tienen prototype; solo las clases y funciones constructoras lo tienen.
¿Cómo funciona la cadena de prototipos?
Cuando llamamos perro1.segundoMetodo(), JavaScript sigue un proceso de búsqueda llamado cadena de prototipos (prototype chain) [4:40]:
- Pregunta a la instancia
perro1: "¿Tienes este método?" — responde que no.
- Sube al prototype de la clase
Perro: "¿Lo tienes tú?" — lo encuentra ahí.
- Devuelve el método y lo ejecuta.
Si tampoco estuviera en Perro, la búsqueda continuaría hacia la clase de la que extiende. En este caso, Perro extiende de Animal, así que subiría a Animal.prototype. Si aún no lo encuentra, llegaría al objeto global Object, que es la raíz de todos los objetos en JavaScript. Más allá de Object solo hay null, y la búsqueda termina [6:55].
¿Cómo visualizar la cadena de prototipos completa?
Para recorrer toda la cadena se puede usar Object.getPrototypeOf() en un bucle [5:30]:
javascript
let prototipoActual = Object.getPrototypeOf(perro1);
while (prototipoActual) {
console.log(prototipoActual);
prototipoActual = Object.getPrototypeOf(prototipoActual);
}
El resultado muestra tres niveles:
- Primer nivel: el prototype de
Perro, con sus métodos compartidos.
- Segundo nivel: el prototype de
Animal, la clase padre de la que extiende Perro.
- Tercer nivel:
Object, el objeto global del cual derivan todos los objetos en JavaScript.
Después de Object se obtiene null, indicando que no hay más eslabones en la cadena [7:40].
Esta interconexión entre objetos es lo que permite la herencia en JavaScript: las instancias acceden a métodos que no definen directamente, pero que heredan a través de la cadena de prototipos de sus clases padre. Comprender este mecanismo te ayuda a extender funcionalidad de forma segura y a evitar el error común de intentar modificar el prototype de una instancia. ¿Has tenido algún problema trabajando con prototipos? Comparte tu experiencia en los comentarios.