
La herencia de prototipos es posiblemente el aspecto menos entendido de JavaScript. Bueno, la buena noticia es que si comprende cómo funciona CSS, también puede comprender cómo funcionan los prototipos de JavaScript.
Es hermoso cuando algo simple es capaz de explicar algo aparentemente complejo, una analogía, como un martillo clava un poste profundamente en el suelo, una analogía lleva el punto a casa.
Soy un amante de las analogías, una analogía.
Aquí vamos.
Prototipos en botones CSS

¿Ves los dos botones de arriba? Los diseñaremos en CSS.
Sigamos adelante y escribamos rápidamente estilos para estos dos botones, comenzando con .btn
.btn { min-width: 135px; min-height: 45px; font-family: ‘Avenir Next’, sans-serif; font-size: 18px; font-weight: bold; letter-spacing: 1.3px; color: #4D815B; background-color: #FFF; border: 2px solid #4D815B; border-radius: 4px; padding: 5px 20px; cursor: pointer;}
Es un bloque de código CSS razonablemente simple.
Ahora pasemos a los estilos para .btn-solid
.btn-solid { min-width: 135px; min-height: 45px; font-family: ‘Avenir Next’, sans-serif; font-size: 18px; font-weight: bold; letter-spacing: 1.3px; color: #FFF; background-color: #4D815B; border: 2px solid #4D815B; border-radius: 4px; padding: 5px 20px; cursor: pointer;}
Como ya habrás notado, aparte de los en negrita, todos los demás estilos .btn-solid
son idénticos al de .btn
. Y si está familiarizado con Sass, es posible que sepa que los .btn-solid
estilos se pueden reescribir en SASS así:
.btn-solid { @extend .btn; color: #FFF; background-color: #4D815B;}

Como puede ver, .btn-solid
hereda estilos de .btn
, luego anula algunos de ellos (fuente y color de fondo) para crearse a sí mismo. Lo que nos lleva a la conclusión de que.btn-solid
es una versión especializada de .btn
. O, en otras palabras, .btn-solid
es .btn
pero con diferentes colores de fuente y fondo. Eso tiene sentido, ¿verdad? Pero espera hay mas.
Digamos que queremos crear un botón grande, .btn-lg
. Lo usaremos .btn
como prototipo para suministrar estilos base. Luego, de manera similar a cómo modificamos el fondo y los colores de fuente para crear .btn-solid
, modificaremos la propiedad de tamaño de fuente a un valor mayor para crear un botón más grande.

Ambos .btn-lg
y .btn-solid
son versiones especializadas de .btn
. .btn
proporciona estilos base .btn-lg
y .btn-solid
que luego sobrescriben algunos de los estilos base para crearlos. Esto nos dice que un solo botón que decidamos, .btn
en nuestro caso, se puede usar como proveedor de estilos base para múltiples artículos.

En esta sección, intentamos definir el concepto de prototipos para botones CSS. Un prototipo es una entidad que proporciona estilos base, que se pueden ampliar para crear diferentes instancias de botones. Esta definición de un prototipo está muy cerca de lo que realmente significan los prototipos en términos de programación.
En términos de programación, un prototipo es un objeto que proporciona un comportamiento básico a un segundo objeto. El segundo objeto luego amplía este comportamiento base para formar su propia especialización. Veamos en la siguiente sección cómo nuestro conocimiento de prototipos en botones CSS se asigna a JavaScript.
Prototipos en JavaScript
Considere el siguiente objeto de JavaScript:
let obj = { a: 1};
Sabemos que a
se puede acceder al valor de obj.a
, dado que a
claramente es una propiedad de obj
. Pero hay más, también puede llamar obj.hasOwnProperty('a')
para verificar si obj
realmente tiene una propiedad nombrada a
.
Ahora espere un segundo, por lo que podemos ver, obj
no tiene hasOwnProperty
definida ninguna propiedad llamada . De donde hasOwnProperty
vino Para responder a esta pregunta tendremos que volver a los botones que acabamos de terminar de crear.
.btn-solid
solo tiene definidos los colores de fondo y fuente. ¿De dónde viene, por ejemplo border-radius
? Sabemos que .btn-solid
es una especialización de .btn
, por lo que podemos ver que .btn-solid
está recibiendo estilos como border-radius
, width
, height
, y padding
de .btn
. ¿Podría ser lo mismo con obj
?
Al igual que .btn-solid
y .btn-lg
obtienen sus estilos base de .btn
, obj
o cualquier otro objeto JavaScript para el caso, reciben su comportamiento base de otro objeto -Object.prototype
. Y esto lo Object.prototype
ha hasOwnProperty
definido. Y como resultado, esto da obj
acceso al hasOwnProperty
método, al igual que .btn-solid
tenía acceso a .btn
la border-radius
propiedad de.

Esto, un objeto (obj) que hereda sus propiedades y comportamiento base de otro objeto (Object.prototype), es lo que llamamos herencia prototípica. Tenga en cuenta que no hay nada class
involucrado en la interacción.
El funcionamiento interno real de los prototipos de JavaScript y nuestros “prototipos” de CSS son muy diferentes. Pero para el propósito de nuestra analogía, podemos ignorar cómo funcionan detrás de escena.
Object.prototype
no es el único prototipo disponible en JavaScript. Hay Array.prototype
, Function.prototype
, Number.prototype
y varios otros. El trabajo de todos estos prototipos es proporcionar comportamiento básico o métodos de utilidad a sus instancias.
Por ejemplo, cada matriz declarada en JavaScript tiene acceso a .push
, .sort
, .forEach
, y .map
sólo debido a la vinculación de prototipos. Y por la misma razón, cada función tiene acceso a .call
, .apply
, .bind
.
Los prototipos y la herencia de prototipos no son específicos de JavaScript. Son una construcción que JavaScript usa internamente y que nos permite usarla en nuestros propios programas. Antes de ver cómo podemos hacer eso exactamente, debemos comprender qué es el encadenamiento de prototipos.
Encadenamiento de prototipos
Tendremos que volver a la analogía de los botones por una vez. Digamos que quiero crear un botón sólido grande .btn-solid-lg
:

Los estilos base .btn-solid-lg
son proporcionados por .btn-solid
y .btn-solid-lg
sobrescribe la propiedad font-size para crearse a sí mismo.
Sin embargo, échale un vistazo más de cerca. .btn-solid
tiene solo dos estilos de color de fondo y color (fuente) definidos en él. Esto significa que .btn-solid-lg
tiene solo 3 estilos para sí mismo: color de fondo, color y tamaño de fuente. ¿Dónde están width
, height
, border-radius
viniendo?
Ok, aquí tienes una pista:

If you wanted to create an extra large button .btn-solid-xlg
you could do so with .btn-solid-lg
as prototype. But how does all of this map to JavaScript?
In JavaScript, you’re allowed to create prototype chains too. Once you understand this, you unlock a whole set of tools to write amazingly powerful code. Yes, amazingly powerful.
Let’s see how prototype chains in JavaScript work.
Remember the object we created in the previous section? The one we carefully named obj
? Did you know that you can create as many objects as you want with obj
as a prototype?
Object.create
lets you create a new object from a specified prototype object. This means that you can create another object, obj2
, which has obj
as its first prototype:
let obj2 = Object.create(obj);
// Add a property 'b' to obj2obj2.b = 2;
If you have been following so far, you should realize that even though obj2
doesn’t have a property a
defined on it, doing console.log(obj2.a)
won’t result in an error, but instead 1
getting logged to the console. Kind of like this:

When obj2
looks for a
, it first searches its own properties. If it can’t find the corresponding property, it asks its prototype (obj), where it finally finds a
. If such was the case that it still couldn’t find a
, the search would continue up the prototype chain until it reaches the last link, Object.prototype
.
On the other hand, if a
was defined on obj2
, it would override all other a
s if defined on any of its prototypes. Similar to how .btn-solid
overrode .btn
's color
and background-color
properties. This is called property overshadowing.
But what about the length of prototype chain? Is there a limit?
There’s no limit to the length of prototype chain. There also aren’t any limits on branching. This means you can create multiple instances with Object.prototype
, obj
, or obj2
as prototype.

So how will this new knowledge of prototypes and prototypal chaining help you write better code?
Writing better code with Prototypes
The goal of this article was to explain to you what prototypes are, and how prototypal inheritance works. I hope I’ve succeeded in this.
For this last section, I’ll allow myself to go on a little rant. I hope you don’t mind.
If you look at the JavaScript code available online — whether in open source projects on Github or in pens on Codepen — you’ll find that a majority of them use the constructor pattern for creating objects.
function Circle(radius) { this.radius = radius;}
Circle.prototype.area = function() { return Math.PI * this.radius * this.radius;}
// Constructor pattern for creating new objectslet circ = new Circle(5);
The constructor pattern looks like classes. In the early days, when JavaScript was far less popular than what it is today, the new
keyword was added as a marketing strategy.
This indirection was intended to make JavaScript seem more familiar to classically trained programmers. Though it’s debatable how successful it was in doing so, it unintentionally also obscured the true prototypal nature of the language.
The reality is that although constructors look like classes, they don’t behave like classes at all. In JavaScript, there are objects, and objects extending from other objects. Constructors and classes never come into picture. The constructor pattern unnecessarily complicates things, there’s a lot that happens behind the scenes.
I implore you — now that you have a solid understanding of prototypes — to stop using the constructor pattern.
Why not do this instead?
let Circle = { create(radius) { // Creating prototypal linkage using Object.create let obj = Object.create(this); obj.radius = radius; return obj; }, area() { return Math.PI * this.radius * this.radius; }};
let circ = Circle.create(5);
I hope this analogy has helped you better understand prototypes, prototypal chaining and prototypal inheritance with Object.create
. Now you can write better code, and stop using pretentious classes.
Thanks for reading! If my article was helpful, click the little green heart below to recommend it, and please share this with your fellow devs.
And for further reading, check out Aadit Shah’s Why Prototypal Inheritance Matters.
Looking for more? I publish regularly on my blog at nashvail.me. See you there, have a good one!
