Réponses
Trop de publicités?J'ai essayé d'envelopper ma tête autour de cela récemment et enfin est venu avec cette "carte" qui, je pense, jette la lumière sur la question
http://i.stack.imgur.com/KFzI3.png
Je sais que je suis pas le premier à faire cela, mais il était plus intéressant en train de comprendre que le fait de trouver ça :-). De toute façon, après que j'ai trouvé, par exemple, cette autre schéma qui, je pense, dit fondamentalement la même:
Javascript disposition de l'objet
La chose la plus surprenante pour moi a été de découvrir qu' Object.__proto__
points de Function.prototype
, au lieu de Object.prototype
, mais je suis sûr qu'il y a une bonne raison à cela :-)
Je collez le code mentionné dans l'image pour si quelqu'un veut le tester. Notez que certaines propriétés sont ajoutées aux objets pour la préparation facile de savoir où nous en sommes après quelques sauts:
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);
constructor
est un pré-définies [[DontEnum]] propriété de l'objet pointé par l' prototype
de la propriété d'un objet de fonction et d'abord du point de la fonction de l'objet lui-même.
__proto__
est équivalent à l'interne [[Prototype]] propriété d'un objet, c'est à dire sa véritable prototype.
Lorsque vous créez un objet à l' new
de l'opérateur, son intérieur [[Prototype]] propriété est définie à l'objet pointé par le constructeur de la fonction de l' prototype
de la propriété.
Cela signifie qu' .constructor
donnera .__proto__.constructor
, c'est à dire la fonction de constructeur utilisé pour créer l'objet, et comme nous l'avons appris, de la protoype
de la propriété de cette fonction a été utilisée pour définir l'objet de la [[Prototype]].
Il s'ensuit qu' .constructor.prototype.constructor
est identique à .constructor
(tant que ces propriétés n'ont pas été écrasés); voir ici pour une explication plus détaillée.
Si __proto__
est disponible, vous pouvez marcher le véritable prototype de la chaîne de l'objet. Il n'y a pas moyen de le faire dans la plaine ECMAScript3 parce que JavaScript n'a pas été conçu pour la profondeur des hiérarchies d'héritage.
Les Prototypes de l'Héritage en JavaScript est basé sur __proto__
propriété dans un sens que chaque objet est hérité du contenu de l'objet référencé par son __proto__
de la propriété.
L' prototype
propriété est spéciale seulement pour Function
objets et uniquement lors de l'utilisation d' new
opérateur d'appeler un Function
comme constructeur. Dans ce cas, l'objet créé l' __proto__
sera mis à du constructeur Function.prototype
.
Cela signifie que l'ajout d' Function.prototype
reflète automatiquement sur tous les objets dont l' __proto__
fait référence à l' Function.prototype
.
Le remplacement du constructeur Function.prototype
avec un autre objet sera pas de mise à jour de __proto__
de la propriété de tout le déjà des objets existants.
Notez que __proto__
propriété ne doit pas être accessible directement, Objet.getPrototypeOf(objet) doit être utilisé à la place.
Pour répondre à la première question, j'ai créé une grille d'diagramme de __proto__
et prototype
références, malheureusement stackoverflow ne me permet pas d'ajouter l'image avec "moins de 10 réputation". Peut-être une autre fois.
[Modifier]
La figure utilise [[Prototype]]
au lieu de __proto__
parce que c'est la façon dont spécification ECMAScript se réfère à des objets internes. J'espère que vous pourrez tout comprendre.
Voici quelques conseils pour vous aider à comprendre la figure:
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)
Notez que constructor
propriété n'existe pas dans créé des objets, mais est hérité du prototype.
Object
Eve, et Function
est Adam, Adam (Function
) utilise son os (Function.prototype
) pour créer Eve (Object
). Alors qui a créé Adam (Function
)? -- L'Inventeur du langage JavaScript :-).
Selon utsaina réponse, je veux ajouter des infos utiles.
La chose la plus surprenante pour moi a été de découvrir qu'
Object.__proto__
points deFunction.prototype
, au lieu deObject.prototype
, mais je suis bien sûr, il ya une bonne raison à cela :-)
Il ne devrait PAS être. Object.__proto__
ne doit PAS pointer vers Object.prototype
. Au lieu de cela, l'instance de Object
o
, o.__proto__
doivent pointer vers l' Object.prototype
.
(Pardonnez-moi pour l'utilisation des termes class
et instance
en JavaScript, mais vous le savez :-)
Je pense que la classe Object
lui-même est une instance de l' Function
, c'est pourquoi Object.__proto__ === Function.prototype
. Donc: Object
Eve, et Function
est Adam, Adam (Function
) utilise son os (Function.prototype
) pour créer Eve (Object
).
En outre, même de la classe Function
lui-même est une instance de l' Function
lui-même, c'est - Function.__proto__ === Function.prototype
, c'est pourquoi Function === Function.constructor
En outre en outre, la classe régulière Cat
est une instance de l' Function
, c'est - Cat.__proto__ === Function.prototype
.
La raison de ce qui précède est, lorsque nous créons une classe en JavaScript, en fait, nous sommes juste de créer une fonction, qui doit être une instance d' Function
. Object
et Function
sont juste spéciales, mais ils sont toujours en cours, alors que Cat
est une classe ordinaire.
Comme une question de fait, Google Chrome moteur JavaScript, les 4 suivants:
Function.prototype
Function.__proto__
Object.__proto__
Cat.__proto__
Ils sont tous ===
(tout à fait égal) pour les 3 autres, et leur valeur est 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
OK. Alors qui crée la spéciale function Empty() {}
(Function.prototype
)? Pensez-y :-)