__proto__ VS. prototipo en JavaScript
Esta figura muestra nuevamente que cada objeto tiene un prototipo. La función constructora Foo también tiene la suya propia
__proto__
, que es Function.prototype, y que a su vez también hace referencia a través de su__proto__
propiedad nuevamente a Object.prototype. Por lo tanto, repito, Foo.prototype es solo una propiedad explícita de Foo que se refiere al prototipo de los objetos b y c.
var b = new Foo(20);
var c = new Foo(30);
¿Cuáles son las diferencias entre __proto__
y prototype
?
La cifra fue tomada de dmitrysoshnikov.com .
Nota: ahora existe una segunda edición (2017) del artículo de 2010 anterior.
__proto__
es el objeto real que se usa en la cadena de búsqueda para resolver métodos, etc. prototype
es el objeto que se usa para construir __proto__
cuando creas un objeto con new
:
( new Foo ).__proto__ === Foo.prototype
( new Foo ).prototype === undefined
prototype
es una propiedad de un objeto Función. Es el prototipo de objetos construidos por esa función.
__proto__
es una propiedad interna de un objeto, que apunta a su prototipo. Las normas actuales proporcionan un método equivalente Object.getPrototypeOf(obj)
, aunque la norma de facto __proto__
es más rápida.
Puede encontrar instanceof
relaciones comparando la cadena de una función prototype
con la de un objeto __proto__
y puede romper estas relaciones cambiando prototype
.
function Point(x, y) {
this.x = x;
this.y = y;
}
var myPoint = new Point();
// the following are all true
console.log(myPoint.__proto__ == Point.prototype);
console.log(myPoint.__proto__.__proto__ == Object.prototype);
console.log(myPoint instanceof Point);
console.log(myPoint instanceof Object);
Aquí Point
hay una función constructora que construye un objeto (estructura de datos) de forma procesal. myPoint
es un objeto construido por Point()
so Point.prototype
se guarda myPoint.__proto__
en ese momento.
prototype
La propiedad se crea cuando se declara una función.
Por ejemplo:
function Person(dob){
this.dob = dob
};
Person.prototype
La propiedad se crea internamente una vez que declara la función anterior. Se pueden agregar muchas propiedades Person.prototype
que comparten las Person
instancias creadas con new Person()
.
// adds a new method age to the Person.prototype Object.
Person.prototype.age = function(){return date-dob};
Vale la pena señalar que Person.prototype
es un Object
literal por defecto (se puede cambiar según sea necesario).
Cada instancia creada usando new Person()
tiene una __proto__
propiedad que apunta al archivo Person.prototype
. Esta es la cadena que se utiliza para recorrer y encontrar una propiedad de un objeto en particular.
var person1 = new Person(somedate);
var person2 = new Person(somedate);
crea 2 instancias de Person
, estos 2 objetos pueden llamar al age
método de Person.prototype
as person1.age
,.person2.age
En la imagen de arriba de su pregunta, puede ver que Foo
es a Function Object
y por lo tanto tiene un __proto__
enlace al Function.prototype
que a su vez es una instancia de Object
y tiene un __proto__
enlace a Object.prototype
. El enlace proto termina aquí __proto__
apuntando Object.prototype
a null
.
Cualquier objeto puede tener acceso a todas las propiedades de su protocadena vinculadas por __proto__
, formando así la base para la herencia prototípica.
__proto__
No es una forma estándar de acceder a la cadena de prototipos, el enfoque estándar pero similar es utilizar Object.getPrototypeOf(obj)
.
El siguiente código para instanceof
el operador brinda una mejor comprensión:
El operador de clase de objeto instanceof
regresa true
cuando un objeto es una instancia de una clase, más específicamente si Class.prototype
se encuentra en la cadena proto de ese objeto, entonces el objeto es una instancia de esa clase.
function instanceOf(Func){
var obj = this;
while(obj !== null){
if(Object.getPrototypeOf(obj) === Func.prototype)
return true;
obj = Object.getPrototypeOf(obj);
}
return false;
}
El método anterior se puede llamar como: instanceOf.call(object, Class)
que devuelve verdadero si el objeto es una instancia de Clase.