Lección 3 · 3 de 20
Prototipos y su cadena · JavaScript
Descubra cómo hereda JavaScript de verdad: prototipos, Object.create, funciones constructoras y la cadena que termina en null.

En JavaScript, cada objeto tiene un enlace oculto a otro objeto: su prototipo. Cuando se pide una propiedad que el objeto no tiene, el lenguaje la busca en el prototipo, después en el prototipo de este, y así sucesivamente. Ese recorrido es la cadena de prototipos.
Object.create(product) crea laptop con product como prototipo. laptop solo tiene name y price; describe no es suya (Object.hasOwn da false), pero la encuentra subiendo por la cadena. Dentro de describe, this sigue siendo laptop, por eso escribe su nombre y su precio.
Antes de que existieran las clases se usaban funciones constructoras. new User(...) crea un objeto vacío, le asigna User.prototype como prototipo y ejecuta la función con this apuntando a él. Los métodos se añaden a User.prototype, de modo que todos los usuarios comparten la misma función: ana.greet === luis.greet es true y no se duplica en memoria.
Si un objeto define una propiedad con el mismo nombre, esta tapa la del prototipo: luis.greet tiene su propia versión y ana sigue usando la compartida. El bucle final recorre la cadena con Object.getPrototypeOf hasta llegar a null. De Object.prototype salen métodos como toString o hasOwnProperty, que tienen todos los objetos.
Código · main.js
const product = { describe() { return `${this.name} - ${this.price.toFixed(2)} EUR`; },};// laptop's prototype is product, so it inherits describe().const laptop = Object.create(product);laptop.name = "Laptop";laptop.price = 899;console.log(laptop.describe());console.log("Own describe?", Object.hasOwn(laptop, "describe"));console.log("Prototype is product?", Object.getPrototypeOf(laptop) === product);// Constructor functions share methods through .prototype.function User(name, role) { this.name = name; this.role = role;}User.prototype.greet = function () { return `Hi, I am ${this.name} (${this.role})`;};const ana = new User("Ana", "admin");const luis = new User("Luis", "editor");console.log(ana.greet());console.log("Same function in both?", ana.greet === luis.greet);luis.greet = () => "Luis says hello his own way"; // own property shadows the prototypeconsole.log(luis.greet(), "|", ana.greet());// The chain ends in Object.prototype, then null.const names = new Map([[User.prototype, "User.prototype"], [Object.prototype, "Object.prototype"]]);const chain = [];for (let p = Object.getPrototypeOf(ana); p; p = Object.getPrototypeOf(p)) chain.push(names.get(p));console.log("ana ->", chain.join(" -> "), "-> null");Salida · node main.js
Laptop - 899.00 EUR Own describe? false Prototype is product? true Hi, I am Ana (admin) Same function in both? true Luis says hello his own way | Hi, I am Ana (admin) ana -> User.prototype -> Object.prototype -> null
Para recordar
- Cada objeto tiene un prototipo, y las propiedades que le faltan se buscan en él.
Object.create(proto)crea un objeto con el prototipo que usted elija.- Los métodos en
Constructor.prototypese comparten entre todas las instancias. - Una propiedad propia tapa la del prototipo con el mismo nombre.
- La cadena termina en
Object.prototypey, después, ennull.
Ejercicio
Añada a User.prototype un método isAdmin() que devuelva true si role es admin, y compruebe con Object.hasOwn que el método no está en ana sino en su prototipo.