Antes de aprender los prototipos, no dejes de consultar estos tutoriales:
- Objetos de JavaScript
- Función constructora de JavaScript
Como sabes, puedes crear un objeto en JavaScript utilizando una función constructora de objetos. Por ejemplo,
// constructor functionfunction Person () { this.name = 'John', this.age = 23}// creating objectsconst person1 = new Person();const person2 = new Person();
En el ejemplo anterior, function Person()
es una función constructora de objetos. Hemos creado dos objetos person1
y person2
a partir de ella.
Prototipo de JavaScript
En JavaScript, cada función y objeto tiene una propiedad llamada prototipo por defecto. Por ejemplo,
function Person () { this.name = 'John', this.age = 23}const person = new Person();// checking the prototype valueconsole.log(Person.prototype); // { ... }
En el ejemplo anterior, estamos intentando acceder a la propiedad prototype de una función constructora Person
.
Como la propiedad prototype no tiene valor por el momento, muestra un objeto vacío { … }.
Herencia del prototipo
En JavaScript, un prototipo se puede utilizar para añadir propiedades y métodos a una función constructora. Y los objetos heredan propiedades y métodos de un prototipo. Por ejemplo,
// constructor functionfunction Person () { this.name = 'John', this.age = 23}// creating objectsconst person1 = new Person();const person2 = new Person();// adding property to constructor functionPerson.prototype.gender = 'male';// prototype value of Personconsole.log(Person.prototype);// inheriting the property from prototypeconsole.log(person1.gender);console.log(person2.gender);
Salida
{ gender: "male" }malemale
En el programa anterior, hemos añadido una nueva propiedad gender
a la función constructora Person
utilizando:
Person.prototype.gender = 'male';
Entonces el objeto person1
y person2
hereda la propiedad gender
de la propiedad prototype de la función constructora Person
.
person1
como person2
pueden acceder a la propiedad gender.
Nota: La sintaxis para añadir la propiedad a una función constructora de objetos es:
objectConstructorName.prototype.key = 'value';
El prototipo se utiliza para proporcionar una propiedad adicional a todos los objetos creados desde una función constructora.
Añadir métodos a una función constructora usando el prototipo
También puedes añadir nuevos métodos a una función constructora usando el prototipo. Por ejemplo,
// constructor functionfunction Person () { this.name = 'John', this.age = 23}// creating objectsconst person1 = new Person();const person2 = new Person();// adding a method to the constructor functionPerson.prototype.greet = function() { console.log('hello' + ' ' + this.name);}person1.greet(); // hello Johnperson2.greet(); // hello John
En el programa anterior, se añade un nuevo método greet
a la función constructora Person
utilizando un prototipo.
Cambio de prototipo
Si se cambia el valor de un prototipo, todos los nuevos objetos tendrán el valor de la propiedad cambiada. Todos los objetos creados previamente tendrán el valor anterior. Por ejemplo,
// constructor functionfunction Person() { this.name = 'John'}// add a propertyPerson.prototype.age = 20;// creating an objectconst person1 = new Person();console.log(person1.age); // 20// changing the property value of prototypePerson.prototype = { age: 50 }// creating new objectconst person3 = new Person();console.log(person3.age); // 50console.log(person1.age); // 20
Nota: No debes modificar los prototipos de los objetos incorporados estándar de JavaScript como cadenas, arrays, etc. Se considera una mala práctica.
Encadenamiento de prototipos de JavaScript
Si un objeto intenta acceder a la misma propiedad que está en la función constructora y en el objeto prototipo, el objeto toma la propiedad de la función constructora. Por ejemplo,
function Person() { this.name = 'John'}// adding property Person.prototype.name = 'Peter';Person.prototype.age = 23const person1 = new Person();console.log(person1.name); // Johnconsole.log(person1.age); // 23
En el programa anterior, se declara un nombre de propiedad en la función constructora y también en la propiedad prototipo de la función constructora.
Cuando el programa se ejecuta, person1.name
busca en la función constructora si hay una propiedad llamada name
. Como la función constructora tiene la propiedad name con valor 'John'
, el objeto toma valor de esa propiedad.
Cuando el programa se ejecuta, person1.age
busca en la función constructora si hay una propiedad llamada age
. Como la función constructora no tiene la propiedad age
, el programa busca en el objeto prototipo de la función constructora y el objeto hereda la propiedad del objeto prototipo (si está disponible).
Nota: También se puede acceder a la propiedad del prototipo de una función constructora desde un objeto.
function Person () { this.name = 'John'}// adding a prototypePerson.prototype.age = 24;// creating objectconst person = new Person();// accessing prototype propertyconsole.log(person.__proto__); // { age: 24 }
En el ejemplo anterior, se utiliza un objeto person
para acceder a la propiedad del prototipo utilizando __proto__
. Sin embargo, __proto__
ha quedado obsoleto y debes evitar su uso.