other objects inherit herencia from ejemplos javascript inheritance prototype-programming

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:

Diseño de objetos JavaScript

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__ :

  1. Cuando crea un objeto con el new operador, su propiedad interna [[Prototype]] / proto__ se establecerá en la propiedad prototype (1) de su constructor function o "creador" si lo desea.

  2. Object.prototype.__proto__ en JS -: Object.prototype.__proto__ es null .

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 a Function.prototype , en lugar de Object.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 :-)