herencia - Relación entre[[Prototype]] y prototipo en JavaScript
object.create javascript (3)
De http://www.jibbering.com/faq/faq_notes/closures.html :
Nota: ECMAScript define una propiedad interna [[prototipo]] del tipo de Objeto interno. A esta propiedad no se puede acceder directamente con scripts, pero es la cadena de objetos a la que se hace referencia con la propiedad interna [[prototipo]] que se usa en la resolución de acceso de propiedad; la cadena de prototipos del objeto. Existe una propiedad de prototipo público para permitir la asignación, definición y manipulación de prototipos en asociación con la propiedad interna [[prototipo]]. Los detalles de la relación entre dos se describen en ECMA 262 (3ª edición) y están fuera del alcance de esta discusión.
¿Cuáles son los detalles de la relación entre los dos? He navegado a través de ECMA 262 y todo lo que he leído allí es cosas como:
El prototipo asociado del constructor puede ser referenciado por el programa expression constructor.prototype,
Los objetos ECMAScript nativos tienen una propiedad interna llamada [[Prototype]]. El valor de esta propiedad es nulo o un objeto y se usa para implementar la herencia.
Cada función incorporada y cada constructor incorporado tiene el objeto prototipo Function, que es el valor inicial de la expresión Function.prototype
Cada objeto prototipo incorporado tiene el objeto prototipo Object, que es el valor inicial de la expresión Object.prototype (15.3.2.1), como el valor de su propiedad interna [[Prototype]], excepto el objeto prototipo Object en sí mismo.
De esto, todo lo que veo es que la propiedad [[Prototype]] es equivalente a la propiedad del prototype
para casi cualquier objeto. ¿Estoy equivocado?
Además de la respuesta de Olavk: Algunas implementaciones de JavaScript (por ejemplo, las de Mozilla ) permiten acceder a la propiedad [[Prototype]] directamente ...
Para responder a su pregunta directamente: lógicamente es la copia privada de un objeto de la propiedad prototype
de su constructor. Usando el metalenguaje, así es como se crean los objetos:
// not real JS
var Ctr = function(...){...};
Ctr.prototype = {...}; // some object with methods and properties
// the object creation sequence: var x = new Ctr(a, b, c);
var x = {};
x["[[prototype]]"] = Ctr.prototype;
var result = Ctr.call(x, a, b, c);
if(typeof result == "object"){ x = result; }
// our x is fully constructed and initialized at this point
En este punto podemos modificar el prototipo, y el cambio será reflejado por todos los objetos de la clase, ya que se refieren al prototipo por referencia:
Ctr.prototype.log = function(){ console.log("...logging..."); };
x.log(); // ...logging..
Pero si cambiamos el prototipo en el constructor, los objetos ya creados seguirán refiriéndose al objeto viejo:
Ctr.prototype = {life: 42};
// let''s assume that the old prototype didn''t define "life"
console.log(x.life); // undefined
x.log(); // ...logging...
De acuerdo con el estándar [[prototype]]
no está disponible, pero Mozilla amplía el estándar con la propiedad __proto__
(solo lectura), que expone el [[prototype]]
normalmente oculto [[prototype]]
:
- la documentación de Mozilla
- descripción general de las extensiones de Mozilla: __count__, __proto__, __parent__
De nuevo, __proto__
puede legalizarse en el próximo estándar ES3.1 .
Creo que tienes razón en la mayoría de los casos.
Cada objeto tiene una propiedad oculta [[Prototype]]
, que se utiliza para la herencia. Las funciones también tienen una propiedad de prototype
público, que se usa solo cuando la función se usa como constructor: cuando un objeto se construye usando new
, la propiedad [[Prototype]]
del nuevo objeto se establece en la propiedad prototype
de la función que era usado como constructor
P.ej
function C() {}
C.prototype = P1;
var obj = new C(); // obj.[[Prototype]] is now P1.
Puede obtener la propiedad [[Prototype]]
usando Object.getPrototypeOf(<obj>)
. (Este método se especifica en ECMAScript 5. Las versiones anteriores de JavaScript no tienen ninguna forma estándar de lectura [[Prototype]]
).
Por lo general, puedes acceder al prototipo a través del constructor, por ejemplo:
obj.constructor.prototype == Object.getPrototypeOf(obj)
Pero este no es siempre el caso, ya que la propiedad prototipo de la función constructora se puede reasignar, pero el [[Prototype]]
de un objeto no se puede reasignar después de que se crea el objeto. Entonces si lo haces:
C.prototype = P2;
entonces
obj.constructor.prototype != Object.getPrototypeOf(obj)
Porque el prototipo de C
ahora es P2
, pero [[Prototype]]
de obj
sigue siendo P1
.
Tenga en cuenta que solo las funciones tienen una propiedad prototype
. Tenga en cuenta también que la propiedad prototype
de una función no es lo mismo que la propiedad [[Prototype]]
de la función.