¿Qué son las Cadenas de Prototipos en JavaScript?

febrero 17, 2025

En JavaScript, las funciones pueden tener propiedades. Todas las funciones tienen una propiedad especial llamada prototype.

function doSomething() {} 
console.log(doSomething.prototype); 
// Las funciones en JavaScript siempre tienen una propiedad prototype por defecto
// Excepción: las funciones flecha no tienen la propiedad prototype por defecto
const doSomethingFromArrowFunction = () => {}; 
console.log(doSomethingFromArrowFunction.prototype); 

doSomething() tiene una propiedad prototype por defecto. Después de ejecutar el código anterior, la consola mostrará un objeto similar al siguiente:

{ constructor: ƒ doSomething(), [[Prototype]]: { constructor: ƒ Object(), hasOwnProperty: ƒ hasOwnProperty(), isPrototypeOf: ƒ isPrototypeOf(), propertyIsEnumerable: ƒ propertyIsEnumerable(), toLocaleString: ƒ toLocaleString(), toString: ƒ toString(), valueOf: ƒ valueOf() } } 

Nota: La consola de Chrome usa [[Prototype]] para representar el prototipo del objeto, según la terminología de la especificación; Firefox usa .prototype. Para mantener la consistencia, usaremos [[Prototype]].

Podemos agregar propiedades al prototipo de doSomething():

function doSomething() {} 
doSomething.prototype.foo = "bar"; 
console.log(doSomething.prototype); 

Resultado:

{ foo: "bar", constructor: ƒ doSomething(), [[Prototype]]: { constructor: ƒ Object(), hasOwnProperty: ƒ hasOwnProperty(), isPrototypeOf: ƒ isPrototypeOf(), propertyIsEnumerable: ƒ propertyIsEnumerable(), toLocaleString: ƒ toLocaleString(), toString: ƒ toString(), valueOf: ƒ valueOf() } } 

Usamos el operador new para crear una instancia de doSomething() basada en este prototipo. Llamar a la función con el operador new devolverá un objeto que es una instancia de la función. Las propiedades pueden agregarse a este objeto.

function doSomething() {} 
doSomething.prototype.foo = "bar"; // agregamos una propiedad al prototipo
const doSomeInstancing = new doSomething(); 
doSomeInstancing.prop = "some value"; // agregamos una propiedad al objeto
console.log(doSomeInstancing); 

Resultado:

{ prop: "some value", [[Prototype]]: { foo: "bar", constructor: ƒ doSomething(), [[Prototype]]: { constructor: ƒ Object(), hasOwnProperty: ƒ hasOwnProperty(), isPrototypeOf: ƒ isPrototypeOf(), propertyIsEnumerable: ƒ propertyIsEnumerable(), toLocaleString: ƒ toLocaleString(), toString: ƒ toString(), valueOf: ƒ valueOf() } } } 

El [[Prototype]] de doSomeInstancing es doSomething.prototype. Al acceder a una propiedad de doSomeInstancing, el tiempo de ejecución primero verifica si doSomeInstancing tiene esa propiedad.

Si no, el tiempo de ejecución buscará la propiedad en doSomeInstancing.[[Prototype]] (es decir, doSomething.prototype). Si doSomeInstancing.[[Prototype]] tiene la propiedad que se busca, entonces se utilizará esa propiedad.

Si no, se verificará doSomeInstancing.[[Prototype]].[[Prototype]]. Por defecto, el [[Prototype]] de la propiedad prototype de cualquier función es Object.prototype. Por lo tanto, se buscará en doSomeInstancing.[[Prototype]].[[Prototype]] (es decir, doSomething.prototype.[[Prototype]] u Object.prototype). Este proceso se llama cadena de prototipos.

Si la propiedad no se encuentra en doSomeInstancing.[[Prototype]].[[Prototype]], entonces se buscará en doSomeInstancing.[[Prototype]].[[Prototype]].[[Prototype]]. Sin embargo, doSomeInstancing.[[Prototype]].[[Prototype]].[[Prototype]] no existe, ya que Object.prototype.[[Prototype]] es null. Después de que se busca en toda la cadena de prototipos, el tiempo de ejecución afirmará que la propiedad no existe y el valor de la propiedad es undefined.

function doSomething() {} 
doSomething.prototype.foo = "bar"; 
const doSomeInstancing = new doSomething(); 
doSomeInstancing.prop = "some value"; 
console.log("doSomeInstancing.prop: ", doSomeInstancing.prop); 
console.log("doSomeInstancing.foo: ", doSomeInstancing.foo); 
console.log("doSomething.prop: ", doSomething.prop); 
console.log("doSomething.foo: ", doSomething.foo); 
console.log("doSomething.prototype.prop:", doSomething.prototype.prop); 
console.log("doSomething.prototype.foo: ", doSomething.prototype.foo); 

Resultado:


doSomeInstancing.prop: some value
doSomeInstancing.foo: bar
doSomething.prop: undefined
doSomething.foo: undefined
doSomething.prototype.prop: undefined
doSomething.prototype.foo: bar

Leave A Comment

Categorías

Recent Posts

Create your account