Prototipos (Prototypes)
JavaScript es un lenguaje basado en prototipos, por lo tanto entender el objeto prototype
es uno de los conceptos más importantes que los profesionales de JavaScript necesitan saber. Este artículo te dará una breve descripción del objeto prototype
a través de varios ejemplos. Antes de leer este artículo, deberás tener un entendimiento básico de la referencia this
en JavaScript.
Objeto prototype
En honor a la claridad, vamos a examinar el siguiente ejemplo:
function Punto2D(x, y) {
this.x = x;
this.y = y;
}
Al declararse la función Punto2D
, una propiedad predeterminada llamada prototype
será creada para ella (ten en cuenta que, en JavaScript, una función es también un objeto). La propiedad prototype
es un objeto que contiene una propiedad constructor
y su valor es la función Punto2D
: Punto2D.prototype.constructor = Punto2D
. Y cuando tú llamas a Punto2D
con la palabra reservada new
, los objetos recién creados heredarán todas las propiedades de Punto2D.prototype
. Para verificar esto, puedes agregar un método llamado mover
en Punto2D.prototype
de la siguiente manera:
Punto2D.prototype.mover = function(dx, dy) {
this.x += dx;
this.y += dy;
}
var p1 = new Point2D(1, 2);
p1.mover (3, 4);
console.log(p1.x); // 4
console.log(p1.y); // 6
El Point2D.prototype
es llamado objeto prototipo o prototipo del objeto p1
y de cualquier otro objeto creado con la sintaxis new Point2D(...)
. Puedes agregar tantas propiedades al objeto Point2D.prototype
como quieras. Lo que suele hacerse es declarar métodos en Point2D.prototype
y otras propiedades se declararán en la función constructora.
Los objetos integrados en JavaScript se construyen de manera similar. Por ejemplo:
- El prototipo de los objetos creados con la sintaxis
new Object()
o{}
esObject.prototype
- El prototipo de los arreglos creados con la sintaxis
new Array()
o[]
esArray.prototype
- Y es igual con otros objetos integrados como
Date
yRegExp
.
Object.prototype
es heredado por todos los objetos y no tiene prototipo (su prototipo es null
)
Cadena de prototipos
El mecanismo de la cadena del prototipo es simple: cuando accede a una propiedad p
en el objeto obj
, el motor de JavaScript buscará esta propiedad dentro del objeto obj
. Si el motor falla en la búsqueda, continúa buscando en el prototipo de objeto obj
y así sucesivamente hasta llegar a Object.prototype
. Si finalizada la búsqueda no se ha encontrado nada, el resultado será undefined
. Por ejemplo:
var obj1 = {
a: 1,
b: 2
};
var obj2 = Object.create(obj1);
obj2.a = 2;
console.log(obj2.a); // 2
console.log(obj2.b); // 2
console.log(obj2.c); // undefined
En el fragmento de código anterior, la declaración var obj2 = Object.create(obj1)
creará el objeto obj2
con el objeto prototipo obj1
. En otras palabras, obj1
se convierte en el prototipo de obj2
en lugar de Object.prototype
por defecto. Como puedes ver, b
no es una propiedad de obj2
, pero puedes acceder a ella a través de la cadena de prototipos. Sin embargo, para la propiedad c
, se obtiene un valor undefined
porque no se puede encontrar en obj1
y en Object.prototype
.
Clases
En ES2016, ahora podemos usar la palabra clave Class
, así como los métodos mencionados anteriormente para manipular el prototype
. Las clases de JavaScript son atractivas para los desarrolladores con experiencia en programación orientada a objetos, pero esencialmente hace lo mismo que el anterior.
class Rectangle {
constructor(height, width) {
this.height = height
this.width = width
}
get area() {
return this.calcArea()
}
calcArea() {
return this.height * this.width
}
}
const square = new Rectangle(10, 10)
console.log(square.area) // 100
Esto es básicamente lo mismo que:
function Rectangle(height, width) {
this.height = height
this.width = width
}
Rectangle.prototype.calcArea = function calcArea() {
return this.height * this.width
}
Los métodos getter
y setter
en las clases vinculan una propiedad Object a una función que será llamada cuando se busque esa propiedad. Esto es solo azúcar sintáctico para ayudar a que sea más fácil buscar o establecer propiedades.
Más información sobre prototipos de JS:
Traducción del artículo - JavaScript Prototype Explained with Examples