objects - prototype javascript ejemplos
¿Cómo difiere__proto__ de constructor.prototype? (6)
function Gadget(name, color)
{
this.name = name;
this.color = color;
}
Gadget.prototype.rating = 3
var newtoy = new Gadget("webcam", "black")
newtoy.constructor.prototype.constructor.prototype.constructor.prototype
Siempre devuelve el objeto con calificación = 3.
Pero si hago lo siguiente:
newtoy.__proto__.__proto__.__proto__
La cadena termina devolviendo null
.
También en Internet Explorer, ¿cómo verificaría el valor nulo si no hay una propiedad __proto__
?
Cada función crea su prototipo. Y cuando creamos un objeto usando el constructor de la función, entonces la propiedad __proto__ de mi objeto comenzará a apuntar al prototipo de esa función.
He estado tratando de entender esto recientemente y finalmente se me ocurrió este "mapa" que creo que arroja mucha luz sobre el asunto
http://i.stack.imgur.com/KFzI3.png
Sé que no soy el primero en inventarlo, pero fue más interesante descubrir que lo encontré :-). De todos modos, después de eso encontré, por ejemplo, este otro diagrama que creo que dice básicamente lo mismo:
Lo más sorprendente para mí fue descubrir que Object.__proto__
apunta a Function.prototype
, en lugar de Object.prototype
, pero estoy seguro de que hay una buena razón para eso :-)
Pego el código mencionado en la imagen aquí también para si alguien quiere probarlo. Tenga en cuenta que algunas propiedades se agregan a los objetos para que sea más fácil saber dónde estamos después de algunos saltos:
Object.O1='''';
Object.prototype.Op1='''';
Function.F1 = '''';
Function.prototype.Fp1 = '''';
Cat = function(){};
Cat.C1 = '''';
Cat.prototype.Cp1 = '''';
mycat = new Cat();
o = {};
// EDITED: using console.dir now instead of console.log
console.dir(mycat);
console.dir(o);
La herencia de Prototypal en JavaScript se basa en la propiedad __proto__
en el sentido de que cada objeto hereda los contenidos del objeto al que hace referencia su propiedad __proto__
.
La propiedad de prototype
es especial solo para los objetos de Function
y solo cuando se usa un new
operador para llamar a una Function
como constructor. En este caso, el __proto__
del objeto creado se establecerá en Function.prototype
del constructor.
Esto significa que agregar a Function.prototype
se reflejará automáticamente en todos los objetos cuyo __proto__
hace referencia al Function.prototype
.
Sustituir el Function.prototype
del constructor con otro objeto no actualizará la propiedad __proto__
para ninguno de los objetos ya existentes.
Tenga en cuenta que no se debe acceder directamente a la propiedad __proto__
, sino que se debe usar Object.getPrototypeOf(object) .
Para responder a la primera pregunta, he creado un diagrama a medida de __proto__
y referencias de prototype
, lamentablemente no me permite agregar la imagen con "menos de 10 de reputación". Quizás en otra ocasión.
[Editar] La figura usa [[Prototype]]
lugar de __proto__
porque así es como la especificación de ECMAScript se refiere a los objetos internos. Espero que puedas descifrar todo.
Aquí hay algunos consejos para ayudarlo a comprender la figura:
red = JavaScript Function constructor and its prototype
violet = JavaScript Object constructor and its prototype
green = user-created objects
(first created using Object constructor or object literal {},
second using user-defined constructor function)
blue = user-defined function and its prototype
(when you create a function, two objects are created in memory:
the function and its prototype)
Tenga en cuenta que la propiedad del constructor
no existe en los objetos creados, sino que se hereda del prototipo.
Realmente no sé por qué las personas no te corrigieron sobre dónde está el problema real en tu comprensión.
Esto te facilitaría mucho detectar el problema
Entonces, veamos qué está pasando:
var newtoy = new Gadget("webcam", "black")
newtoy
.constructor //newtoy''s constructor function is newtoy ( the function itself)
.prototype // the function has a prototype property.( all functions has)
.constructor // constructor here is a **property** (why ? becuase you just did `prototype.constructor`... see the dot ? ) ! it is not(!) the constructor function !!! this is where your mess begins. it points back to the constructor function itself ( newtoy function)
.prototype // so again we are at line 3 of this code snippet
.constructor //same as line 4 ...
.prototype
rating = 3
Genial, así que ahora veamos este __proto__
Antes de eso, recuerde 2 cosas con respecto a __proto__
:
Cuando crea un objeto con el
new
operador, su propiedad interna[[Prototype]]
/proto__
se establecerá en la propiedadprototype
(1) de suconstructor function
o "creador" si lo desea.Object.prototype.__proto__
en JS -:Object.prototype.__proto__
esnull
.
Vamos a referirnos a estos 2 puntos como " bill
"
newtoy
.__proto__ // When `newtoy` was created , Js put __proto__''s value equal to the value of the cunstructor''s prototype value. which is `Gadget.prototype`.
.__proto__ // Ok so now our starting point is `Gadget.prototype`. so regarding "bill" who is the constructor function now? watch out !! it''s a simple object ! a regular object ! prototype is a regular object!! so who is the constructor function of that object ? Right , it''s the `function Object(){...}`. Ok .( continuing "bill" ) does it has a `prototype` property ? sure. all function has. it''s `Object.prototype`. just remember that when Gadget.prototype was created , it''s internal `__proto__` was refered to `Object.prototype` becuase as "bill" says :"..will be set to the `prototype` property of its `constructor function`"
.__proto__ // Ok so now our satrting point is `Object.prototype`. STOP. read bullet 2.Object.prototype.__proto__ is null by definition. when Object.prototype ( as an object) was created , they SET THE __PROTO__ AS NULL HARDCODED
¿Mejor?
constructor
es una propiedad predefinida [[DontEnum]] del objeto apuntado por la propiedad prototype
de un objeto de función e inicialmente apunta al objeto de función en sí.
__proto__
es equivalente a la propiedad interna [[Prototype]] de un objeto, es decir, su prototipo real.
Cuando crea un objeto con el new
operador, su propiedad interna [[Prototype]] se establecerá en el objeto apuntado por la propiedad del prototype
la función del constructor.
Esto significa que .constructor
evaluará a .__proto__.constructor
.constructor
.__proto__.constructor
, es decir, la función de constructor utilizada para crear el objeto, y como hemos aprendido, la propiedad del protoype
de esta función se usó para establecer el [[Prototype] del objeto].
Se deduce que .constructor.prototype.constructor
es idéntico a .constructor
(siempre que estas propiedades no se hayan sobrescrito); mira here para una explicación más detallada.
Si __proto__
está disponible, puede recorrer la cadena del prototipo real del objeto. No hay forma de hacer esto en ECMAScript3 simple porque JavaScript no fue diseñado para jerarquías de herencia profunda.
Object
es Eva, y la Function
es Adam, Adam ( Function
) usa su hueso ( Function.prototype
) para crear a Eve ( Object
). Entonces, ¿quién creó a Adán ( Function
)? - El inventor del lenguaje JavaScript :-).
De acuerdo con la respuesta de utsaina, quiero agregar más información útil.
Lo más sorprendente para mí fue descubrir que
Object.__proto__
apunta aFunction.prototype
, en lugar deObject.prototype
, pero estoy seguro de que hay una buena razón para eso :-)
NO debería ser Object.__proto__
NO debe apuntar a Object.prototype
. En cambio, la instancia de Object
o
, o.__proto__
debe apuntar a Object.prototype
.
(Perdóneme por usar los términos class
e instance
en JavaScript, pero lo sabe :-)
Creo que el Object
clase en sí es una instancia de Function
, por eso Object.__proto__ === Function.prototype
. Por lo tanto: el Object
es Eva, y la Function
es Adam, Adam ( Function
) usa su hueso ( Function.prototype
) para crear a Eve ( Object
).
Además, incluso la Function
clase en sí misma es una instancia de la Function
sí, que es Function.__proto__ === Function.prototype
, también es la Function === Function.constructor
Además, la clase regular Cat
es una instancia de Function
, que es Cat.__proto__ === Function.prototype
.
La razón de lo anterior es que, cuando creamos una clase en JavaScript, en realidad, solo estamos creando una función, que debería ser una instancia de Function
. Object
y Function
son solo especiales, pero siguen siendo clases, mientras que Cat
es una clase regular.
Como una cuestión de factor, en el motor de JavaScript de Google Chrome, los siguientes 4:
-
Function.prototype
-
Function.__proto__
-
Object.__proto__
-
Cat.__proto__
Son todos ===
(absolutamente iguales) a los otros 3, y su valor es function Empty() {}
> Function.prototype
function Empty() {}
> Function.__proto__
function Empty() {}
> Object.__proto__
function Empty() {}
> Cat.__proto__
function Empty() {}
> Function.prototype === Function.__proto__
true
> Function.__proto__ === Object.__proto__
true
> Object.__proto__ === Cat.__proto__
true
DE ACUERDO. Entonces, ¿quién crea la function Empty() {}
especial function Empty() {}
( Function.prototype
)? Piénsalo :-)