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.prototypeno es igualnewtoy.constructor.prototypey, pornewtoy.constructor.prototypelo tanto , no tendrá una propiedad llamadarating. Del mismo modonewtoy.constructor.prototype.constructor.propertytampoco tendrá propiedad llamadarating.newtoy.constructor.prototypelo tanto, tendrá una propiedad llamada calificación. Del mismo modonewtoy.constructor.prototype.constructor.propertytambién tendrá propiedad llamada calificación.__proto__vs.prototypeen 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.prototypees 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, YArraytodos heredamos el prototipo de función.Objecten 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.constructores una propiedad [[DontEnum]] predefinida del objeto señalado por laprototypepropiedad 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
newoperador, su propiedad interna [[Prototype]] se establecerá en el objeto señalado por la función del constructorprototypepropiedad de .Esto significa que
.constructorse evaluará.__proto__.constructor, es decir, la función constructora utilizada para crear el objeto, y como hemos aprendido, laprotoypepropiedad de esta función se utilizó para establecer el [[Prototipo]] del objeto.Se deduce que
.constructor.prototype.constructores 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.prototypeencadenamiento. Tampoco estaba claro para mí, aunque no vi que eso.constructores 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
prototypepropiedad es especial solo paraFunctionobjetos y solo cuando se utiliza elnewoperador para llamar a unFunctionconstructor. En este caso, los objetos creados__proto__se establecerán en constructoresFunction.prototype.Esto significa que agregar a
Function.prototypese reflejará automáticamente en todos los objetos a los que__proto__se hace referenciaFunction.prototype.Reemplazar el constructor
Function.prototypecon 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__yprototypereferencias 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
constructorpropiedad 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.prototypees un instinto deMyfunction)Objectes Eva, yFunctiones 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 deObjecto,o.__proto__debería apuntar aObject.prototype.(Perdóname por usar los términos
classyinstanceen JavaScript, pero lo sabes :-)Creo que la clase en
Objectsí es una instancia deFunction, por esoObject.__proto__ === Function.prototype. Por lo tanto:Objectes Eva, yFunctiones Adán, Adán (Function) usa su hueso (Function.prototype) para crear Eva (Object).Además, incluso la clase
Functionmisma es una instancia deFunctionsí misma, esFunction.__proto__ === Function.prototypedecir, también es por esoFunction === Function.constructorAdemás, la clase regular
Cates 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.ObjectyFunctionson simplemente especiales, pero siguen siendo clases, mientras queCates una clase regular.Como cuestión de factor, en el motor JavaScript de Google Chrome, los siguientes 4:
Function.prototypeFunction.__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
newoperador, su propiedad[[Prototype]]/ internoproto__se establecerá en laprototypepropiedad (1) de suconstructor functiono "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.prototypeAl 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 laprototypepropiedad de la función.Tenga en cuenta que la
prototypepropiedad 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
Gadgetfunción, también creamos un objeto{constructor: Gadget}, que no se parece en nadaGadget.prototype. Como seconstructorrefiere a una función que creó un prototipo de objeto,toy.constructorrepresenta laGadgetfunción. Escribimostoy.constructor.prototypey 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.prototypey siempre lo seráGadget.prototype.STH .__ proto__
Mientras que
prototypees 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.prototypees un objeto ({}) y los objetos se crean con laObjectfunció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 laprototypepropiedad 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 denewoperador. 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
Functionobjeto de función incorporado que tiene una propiedad especial llamadaprototypeutilizada 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
prototypees 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 elnullvalor.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.prototypees el último en su cadena de prototipos. PeroObject.prototypeno es una instancia deObjectporqueObject.prototype.__proto__tiene el valornull.También puede crear un objeto con un
nullprototipo 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 deObjectya que({}).__proto__es una referencia aObject.prototype.fuente