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 rating = 3.
Pero si hago lo siguiente:
newtoy.__proto__.__proto__.__proto__
La cadena termina volviendo null
.
También en Internet Explorer, ¿cómo comprobaría el valor nulo si no hay una __proto__
propiedad?
javascript
inheritance
prototype-programming
xdevel2000
fuente
fuente
newtoy.prototype
no es igualnewtoy.constructor.prototype
y, pornewtoy.constructor.prototype
lo tanto , no tendrá una propiedad llamadarating
. Del mismo modonewtoy.constructor.prototype.constructor.property
tampoco tendrá propiedad llamadarating
.newtoy.constructor.prototype
lo tanto, tendrá una propiedad llamada calificación. Del mismo modonewtoy.constructor.prototype.constructor.property
también tendrá propiedad llamada calificación.__proto__
vs.prototype
en JavaScript y ¿Cómo funciona JavaScript.prototype
?Respuestas:
He estado tratando de entender esto recientemente y finalmente se me ocurrió este "mapa" que creo que arroja luz sobre el asunto
http://i.stack.imgur.com/KFzI3.png
Sé que no soy el primero en inventar esto, pero fue más interesante descubrir que encontrarlo :-). De todos modos, después de eso encontré, por ejemplo, este otro diagrama que creo que dice básicamente lo mismo:
Diseño de objeto Javascript
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 :-)Pego el código mencionado en la imagen aquí también si alguien quiere probarlo. Tenga en cuenta que algunas propiedades se agregan a los objetos para facilitar saber dónde estamos después de algunos saltos:
fuente
Object.__proto__
apuntaFunction.prototype
es porqueObject()
es una función nativa que crea una instancia de un objeto vacío. Por lo tanto,Object()
es una función. Encontrará que todas las__proto__
propiedades de los otros tipos nativos principales apuntan aFunction.prototype
.Object
,Function
,String
,Number
, YArray
todos heredamos el prototipo de función.Object
en sí mismo es una función; El resultado de ejecutar invocablesObject
(es decir, el valor de retorno de la ejecuciónObject()
) no es una función.constructor
es una propiedad [[DontEnum]] predefinida del objeto señalado por laprototype
propiedad de un objeto de función e inicialmente apuntará 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 señalado por la función del constructorprototype
propiedad de .Esto significa que
.constructor
se evaluará.__proto__.constructor
, es decir, la función constructora utilizada para crear el objeto, y como hemos aprendido, laprotoype
propiedad de esta función se utilizó para establecer el [[Prototipo]] del objeto.Se deduce que
.constructor.prototype.constructor
es idéntico a.constructor
(siempre y cuando estas propiedades no se hayan sobrescrito); Vea aquí para una explicación más detallada.Si
__proto__
está disponible, puede recorrer la cadena de prototipos real del objeto. No hay forma de hacer esto en ECMAScript3 simple porque JavaScript no fue diseñado para jerarquías de herencia profunda.fuente
.constructor.prototype
encadenamiento. Tampoco estaba claro para mí, aunque no vi que eso.constructor
es igual.__proto__.constructor
. Lo que simplemente significa alternar entre la función del constructor y su prototipo.La herencia prototípica en JavaScript se basa en la
__proto__
propiedad en el sentido de que cada objeto hereda el contenido del objeto al que hace referencia su__proto__
propiedad.La
prototype
propiedad es especial solo paraFunction
objetos y solo cuando se utiliza elnew
operador para llamar a unFunction
constructor. En este caso, los objetos creados__proto__
se establecerán en constructoresFunction.prototype
.Esto significa que agregar a
Function.prototype
se reflejará automáticamente en todos los objetos a los que__proto__
se hace referenciaFunction.prototype
.Reemplazar el constructor
Function.prototype
con otro objeto no actualizará la__proto__
propiedad de ninguno de los objetos ya existentes.Tenga en cuenta que
__proto__
no se debe acceder directamente a la propiedad, sino que se debe usar Object.getPrototypeOf (objeto) .Para responder a la primera pregunta, he creado un diagrama
__proto__
yprototype
referencias a medida , desafortunadamente stackoverflow no me permite agregar la imagen con "menos de 10 reputación". Quizás en otra ocasión.[Editar] La figura usa en
[[Prototype]]
lugar de__proto__
porque así es como la especificación ECMAScript se refiere a objetos internos. Espero que puedas resolverlo todo.Aquí hay algunos consejos para ayudarlo a comprender la figura:
Tenga en cuenta que la
constructor
propiedad no existe en los objetos creados, sino que se hereda del prototipo.fuente
new MyFunction()
crea una instancia de objeto que__proto__
debería referirse a su prototipo ctor que esMyFunction.prototype.
Entonces, ¿por qué seMyFunction.prototype.__proto__
refiereObject.prototype
? debería referirse (como mi primera muestra) al prototipo de su ctor que esMyFunction.prototype
(note queMyFunction.prototype
es un instinto deMyfunction
)Object
es Eva, yFunction
es Adán, Adán (Function
) usa su hueso (Function.prototype
) para crear Eva (Object
). Entonces, ¿quién creó a Adam (Function
)? - El inventor del lenguaje JavaScript :-).Según la respuesta de utsaina, quiero agregar más información útil.
NO debería ser.
Object.__proto__
NO debería señalarObject.prototype
. En cambio, la instancia deObject
o
,o.__proto__
debería apuntar aObject.prototype
.(Perdóname por usar los términos
class
yinstance
en JavaScript, pero lo sabes :-)Creo que la clase en
Object
sí es una instancia deFunction
, por esoObject.__proto__ === Function.prototype
. Por lo tanto:Object
es Eva, yFunction
es Adán, Adán (Function
) usa su hueso (Function.prototype
) para crear Eva (Object
).Además, incluso la clase
Function
misma es una instancia deFunction
sí misma, esFunction.__proto__ === Function.prototype
decir, también es por esoFunction === Function.constructor
Además, la clase regular
Cat
es una instancia deFunction
, es decirCat.__proto__ === Function.prototype
.La razón de lo anterior es, cuando creamos una clase en JavaScript, en realidad, solo estamos creando una función, que debería ser una instancia de
Function
.Object
yFunction
son simplemente especiales, pero siguen siendo clases, mientras queCat
es una clase regular.Como cuestión de factor, en el motor JavaScript de Google Chrome, los siguientes 4:
Function.prototype
Function.__proto__
Object.__proto__
Cat.__proto__
Todos son
===
(absolutamente iguales) a los otros 3, y su valor esfunction Empty() {}
OKAY. Entonces, ¿quién crea el especial
function Empty() {}
(Function.prototype
)? Piénsalo :-)fuente
function Empty() {}
refiere como igual a Function.prototype, etc. ?, ¿cuál es el código que usó en la consola de Chrome?function Empty() {}
en Google Chrome. También agregué la salida de la consola._ _proto_ _
) de Function.prototype. Es tan simple como eso :)Realmente no sé por qué la gente no te corrigió sobre dónde está el problema real en tu comprensión.
Esto facilitaría mucho la detección del problema.
Así que veamos qué está pasando:
Genial, ahora veamos esto
__proto__
Antes de eso, recuerde 2 cosas con respecto a
__proto__
:Cuando crea un objeto con el
new
operador, su propiedad[[Prototype]]
/ internoproto__
se establecerá en laprototype
propiedad (1) de suconstructor function
o "creador" si lo desea.Codificado dentro de JS -:
Object.prototype.__proto__
esnull
.Vamos a referirnos a estos 2 puntos como "
bill
"¿Mejor?
fuente
Cada función crea su prototipo. Y cuando creamos un objeto usando el constructor de esa función, la propiedad __proto__ de mi objeto comenzará a apuntar al prototipo de esa función.
fuente
__proto__
propiedad.Si todas esas cifras fueran abrumadoras, echemos un vistazo a lo que significan las propiedades.
STH.prototype
Al crear una nueva función, se crea un objeto vacío en paralelo y se vincula a la función con la
[[Prototype]]
cadena. Para acceder a este objeto, utilizamos laprototype
propiedad de la función.Tenga en cuenta que la
prototype
propiedad solo está disponible para funciones.STH.constructor
El objeto prototipo mencionado anteriormente no tiene propiedades excepto uno -
constructor
. Esta propiedad representa una función que creó el objeto prototipo.Al crear la
Gadget
función, también creamos un objeto{constructor: Gadget}
, que no se parece en nadaGadget.prototype
. Como seconstructor
refiere a una función que creó un prototipo de objeto,toy.constructor
representa laGadget
función. Escribimostoy.constructor.prototype
y estamos recibiendo{constructor: Gadget}
volviendo a .Por lo tanto, hay un círculo vicioso: puedes usarlo
toy.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype
y siempre lo seráGadget.prototype
.STH .__ proto__
Mientras que
prototype
es una propiedad específica para funciones,__proto__
está disponible para todos los objetos tal como se estableceObject.prototype
. Se refiere al prototipo de una función que puede crear un objeto.Aquí
toy.__proto__
estáGadget.prototype
. ComoGadget.prototype
es un objeto ({}
) y los objetos se crean con laObject
función (ver el ejemplo anterior), obtenemosObject.prototype
. Este es el objeto más alto en JavaScript y__proto__
solo puede indicarlonull
.fuente
Respuesta corta:
__proto__
es una referencia a laprototype
propiedad del constructor que creó el objeto.Objetos en JavaScript
Un objeto JavaScript es un tipo integrado para una colección de cero o más propiedades. Las propiedades son contenedores que contienen otros objetos, valores primitivos o funciones.
Constructores en JavaScript
Las funciones son objetos regulares (que se implementan
[[Call]]
en términos de ECMA-262) con la capacidad adicional de ser invocables pero juegan otro papel en JavaScript: se convierten en constructores ( fábricas para objetos) si se invocan a través denew
operador. Los constructores son, pues, un análogo aproximado de las clases en otros idiomas.Cada función de JavaScript es en realidad una instancia del
Function
objeto de función incorporado que tiene una propiedad especial llamadaprototype
utilizada para implementar la herencia basada en prototipos y las propiedades compartidas. Cada objeto creado por una función constructora tiene una referencia implícita (llamada prototipo o__proto__
) al valor de su constructorprototype
.El constructor
prototype
es una especie de plano para construir objetos, ya que cada objeto creado por el constructor hereda una referencia a suprototype
.La cadena prototipo
Un objeto especifica su prototipo mediante la propiedad interna
[[Prototype]]
o__proto__
. La relación prototipo entre dos objetos es sobre herencia: cada objeto puede tener otro objeto como prototipo. El prototipo puede ser elnull
valor.La cadena de objetos conectados por la
__proto__
propiedad se llama cadena prototipo. . Cuando se hace una referencia a una propiedad en un objeto, esa referencia es a la propiedad encontrada en el primer objeto en la cadena de prototipo que contiene una propiedad de ese nombre. La cadena prototipo se comporta como si fuera un solo objeto.Ver esta imagen (extraída de este blog ):
Cada vez que intenta acceder a una propiedad en un objeto, JavaScript comienza la búsqueda de ese objeto y continúa con su prototipo, el prototipo del prototipo y así sucesivamente hasta que se encuentra la propiedad o si
__proto__
contiene el valornull
.Casi todos los objetos son instancias de
Object
, porqueObject.prototype
es el último en su cadena de prototipos. PeroObject.prototype
no es una instancia deObject
porqueObject.prototype.__proto__
tiene el valornull
.También puede crear un objeto con un
null
prototipo como este:Este tipo de objeto es un mejor mapa (diccionario) de un objeto literal, por lo que este patrón es a veces llamado el dict patrón ( dict para el diccionario).
Nota: los objetos literales creados usando
{}
son instancias deObject
ya que({}).__proto__
es una referencia aObject.prototype
.fuente