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
Il renvoie toujours l'objet avec rating = 3.
Mais si je fais ce qui suit:
newtoy.__proto__.__proto__.__proto__
La chaîne finit par revenir null
.
Également dans Internet Explorer, comment puis-je vérifier la valeur null s'il n'y a pas de __proto__
propriété?
javascript
inheritance
prototype-programming
xdevel2000
la source
la source
newtoy.prototype
n'est pas égal ànewtoy.constructor.prototype
etnewtoy.constructor.prototype
n'aura donc pas de propriété appeléerating
. De mêmenewtoy.constructor.prototype.constructor.property
, la propriété ne sera pas appeléerating
.newtoy.constructor.prototype
aura donc la propriété appelée rating. De mêmenewtoy.constructor.prototype.constructor.property
aura également une propriété appelée notation.__proto__
Vs.prototype
en JavaScript et comment fonctionne JavaScript.prototype
?Réponses:
J'ai essayé de comprendre cela récemment et j'ai finalement trouvé cette "carte" qui, je pense, jette toute la lumière sur la question
http://i.stack.imgur.com/KFzI3.png
Je sais que je ne suis pas le premier à inventer ça, mais c'était plus intéressant de comprendre que de le trouver :-). Quoi qu'il en soit, après cela, j'ai trouvé par exemple cet autre diagramme qui, je pense, dit fondamentalement la même chose:
Disposition des objets Javascript
La chose la plus surprenante pour moi a été de découvrir que cela
Object.__proto__
indiqueFunction.prototype
plutôt queObject.prototype
, mais je suis sûr qu'il y a une bonne raison à cela :-)Je colle également le code mentionné dans l'image ici si quelqu'un veut le tester. Notez que certaines propriétés sont ajoutées aux objets pour vous permettre de savoir facilement où nous en sommes après quelques sauts:
la source
Object.__proto__
pointe versFunction.prototype
est parceObject()
qu'en elle-même est une fonction native qui instancie un objet vide. Par conséquent,Object()
est une fonction. Vous constaterez que toutes les__proto__
propriétés des autres principaux types natifs pointent versFunction.prototype
.Object
,Function
,String
,Number
EtArray
tous Hériter le prototype de fonction.Object
elle-même est une fonction; le résultat de l'exécution de callableObject
(c'est-à-dire la valeur de retour de runningObject()
) n'est pas une fonction.constructor
est une propriété [[DontEnum]] prédéfinie de l'objet pointé par laprototype
propriété d'un objet fonction et pointera initialement vers l'objet fonction lui-même.__proto__
équivaut à la propriété [[Prototype]] interne d'un objet, c'est-à-dire son prototype réel.Lorsque vous créez un objet avec l'
new
opérateur, sa propriété interne [[Prototype]] sera définie sur l'objet pointé par laprototype
propriété de la fonction constructeur .Cela signifie que
.constructor
sera évalué à.__proto__.constructor
, c'est- à -dire la fonction constructeur utilisée pour créer l'objet, et comme nous l'avons appris, laprotoype
propriété de cette fonction a été utilisée pour définir le [[Prototype]] de l'objet.Il s'ensuit que
.constructor.prototype.constructor
c'est identique à.constructor
(tant que ces propriétés n'ont pas été écrasées); voir ici pour une explication plus détaillée.S'il
__proto__
est disponible, vous pouvez parcourir la chaîne de prototypes réels de l'objet. Il n'y a aucun moyen de le faire dans ECMAScript3 simple car JavaScript n'a pas été conçu pour les hiérarchies d'héritage profondes.la source
.constructor.prototype
chaînage. Je n'étais pas non plus clair pour moi, alors que je n'ai pas vu que c'était.constructor
égal.__proto__.constructor
. Ce qui signifie simplement passer de la fonction du constructeur à son prototype.L'héritage prototypique en JavaScript est basé sur la
__proto__
propriété dans le sens où chaque objet hérite du contenu de l'objet référencé par sa__proto__
propriété.La
prototype
propriété est spéciale uniquement pour lesFunction
objets et uniquement lors de l'utilisation de l'new
opérateur pour appeler unFunction
constructeur as. Dans ce cas, l'objet créé__proto__
sera défini sur constructeurFunction.prototype
.Cela signifie que l'ajout à
Function.prototype
se reflétera automatiquement sur tous les objets__proto__
référençant leFunction.prototype
.Le remplacement du constructeur
Function.prototype
par un autre objet ne mettra à jour la__proto__
propriété d'aucun des objets déjà existants.Notez que la
__proto__
propriété ne doit pas être accédée directement, Object.getPrototypeOf (object) doit être utilisé à la place.Pour répondre à la première question, j'ai créé un schéma
__proto__
et desprototype
références sur mesure, 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 ainsi que la spécification ECMAScript fait référence aux objets internes. J'espère que vous pourrez tout comprendre.Voici quelques conseils pour vous aider à comprendre la figure:
Notez que la
constructor
propriété n'existe pas dans les objets créés, mais est héritée du prototype.la source
new MyFunction()
crée une instance d'objet qui__proto__
doit faire référence à son prototype ctor qui estMyFunction.prototype.
alors pourquoi faitMyFunction.prototype.__proto__
référenceObject.prototype
? il devrait se référer (comme mon premier échantillon) au prototype de son ctor qui estMyFunction.prototype
(remarquez qu'ilMyFunction.prototype
s'agit d'un instnace deMyfunction
)Object
est Eve, etFunction
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 la réponse de utsaina, je souhaite ajouter des informations plus utiles.
CA ne devrait pas être.
Object.__proto__
ne doit PAS pointer versObject.prototype
. Au lieu de cela, l'instance deObject
o
,o.__proto__
doit pointer versObject.prototype
.(Pardonnez-moi d'utiliser les termes
class
etinstance
en JavaScript, mais vous le savez :-)Je pense que la classe
Object
elle-même est une instance deFunction
, c'est pourquoiObject.__proto__ === Function.prototype
. Par conséquent:Object
est Eve, etFunction
est Adam, Adam (Function
) utilise son os (Function.prototype
) pour créer Eve (Object
).De plus, même la classe
Function
elle-même est une instance d'Function
elle-même, c'est-à-direFunction.__proto__ === Function.prototype
-dire aussi pourquoiFunction === Function.constructor
De plus, la classe régulière
Cat
est une instance deFunction
, c'est-à-direCat.__proto__ === Function.prototype
.La raison de ce qui précède est que lorsque nous créons une classe en JavaScript, en fait, nous créons simplement une fonction, qui devrait être une instance de
Function
.Object
etFunction
sont juste spéciaux, mais ce sont toujours des classes, alors queCat
c'est une classe régulière.En tant que facteur, dans le moteur JavaScript de Google Chrome, les 4 suivants:
Function.prototype
Function.__proto__
Object.__proto__
Cat.__proto__
Ils sont tous
===
(absolument égaux) aux 3 autres, et leur valeur estfunction Empty() {}
D'ACCORD. Alors, qui crée le spécial
function Empty() {}
(Function.prototype
)? Pensez-y :-)la source
function Empty() {}
faites - vous référence pour être égal à Function.prototype, etc.?, Quel est le code que vous avez utilisé dans la console chrome?function Empty() {}
dans Google Chrome. J'ai également ajouté la sortie de la console._ _proto_ _
) de Function.prototype. C'est aussi simple que ça :)Je ne sais vraiment pas pourquoi les gens ne vous ont pas corrigé d'où le problème réel dans votre compréhension.
Cela vous permettrait de repérer beaucoup plus facilement le problème
Voyons donc ce qui se passe:
Super, alors maintenant regardons ça
__proto__
Avant cela, rappelez-vous 2 choses concernant
__proto__
:Lorsque vous créez un objet avec l'
new
opérateur, sa propriété interne[[Prototype]]
/proto__
sera définie sur laprototype
propriété (1) de sonconstructor function
ou "créateur" si vous le souhaitez.Codé en dur dans JS -:
Object.prototype.__proto__
estnull
.Faisons référence à ces 2 points comme "
bill
"Mieux?
la source
Chaque fonction crée son prototype. Et lorsque nous créons un objet en utilisant ce constructeur de fonction, la propriété __proto__ de mon objet commencera à pointer vers le prototype de cette fonction.
la source
__proto__
propriété.Si tous ces chiffres étaient accablants, voyons ce que signifient les propriétés.
STH.prototype
Lors de la création d'une nouvelle fonction, un objet vide est créé en parallèle et lié à la fonction avec
[[Prototype]]
chaîne. Pour accéder à cet objet, nous utilisons laprototype
propriété de la fonction.Gardez à l'esprit que la
prototype
propriété n'est disponible que pour les fonctions.Constructeur STH
L'objet prototype mentionné ci-dessus n'a pas de propriétés sauf une -
constructor
. Cette propriété représente une fonction qui a créé l'objet prototype.Lors de la création d'une
Gadget
fonction, nous avons également créé un objet similaire{constructor: Gadget}
- cela n'a rien à voir avecGadget.prototype
. Asconstructor
fait référence à une fonction qui a créé un prototype d'objet,toy.constructor
représente uneGadget
fonction. Nous écrivonstoy.constructor.prototype
et nous obtenons{constructor: Gadget}
recommençons.Par conséquent, il existe un cercle vicieux: vous pouvez utiliser
toy.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype
et ce sera toujours le casGadget.prototype
.STH .__ proto__
While
prototype
est une propriété spécifique pour les fonctions,__proto__
est disponible pour tous les objets au fur et à mesureObject.prototype
. Il fait référence au prototype d'une fonction qui peut créer un objet.Voilà,
toy.__proto__
c'estGadget.prototype
. CommeGadget.prototype
un objet ({}
) et que les objets sont créés avec laObject
fonction (voir l'exemple ci-dessus), nous obtenonsObject.prototype
. C'est l'objet le plus élevé en JavaScript et__proto__
il ne peut que l'indiquernull
.la source
Réponse courte:
__proto__
est une référence à laprototype
propriété du constructeur qui a créé l'objet.Objets en JavaScript
Un objet JavaScript est un type intégré pour une collection de zéro ou plusieurs propriétés. Les propriétés sont des conteneurs qui contiennent d'autres objets, valeurs primitives ou fonctions.
Constructeurs en JavaScript
Les fonctions sont des objets réguliers (qui implémentent
[[Call]]
en termes ECMA-262) avec la capacité supplémentaire d'être appelables mais jouent un autre rôle en JavaScript: elles deviennent des constructeurs ( usines pour objets) si elles sont appelées via lenew
opérateur. Les constructeurs sont donc un analogue approximatif aux classes d'autres langages.Chaque fonction JavaScript est en fait une instance de l'
Function
objet fonction intégré qui possède une propriété spéciale nomméeprototype
utilisée pour implémenter l'héritage basé sur un prototype et les propriétés partagées. Chaque objet créé par une fonction constructeur a une référence implicite (appelée prototype ou__proto__
) à la valeur de son constructeurprototype
.Le constructeur
prototype
est une sorte de modèle pour la construction d'objets puisque chaque objet créé par le constructeur hérite d'une référence à sonprototype
.La chaîne prototype
Un objet spécifie son prototype via la propriété interne
[[Prototype]]
ou__proto__
. La relation prototype entre deux objets concerne l'héritage: chaque objet peut avoir un autre objet comme prototype. Le prototype peut être lanull
valeur.La chaîne d'objets connectés par la
__proto__
propriété est appelée la chaîne prototype . Lorsqu'une référence est faite à une propriété dans un objet, cette référence est à la propriété rencontrée dans le premier objet de la chaîne prototype qui contient une propriété de ce nom. La chaîne prototype se comporte comme s'il s'agissait d'un seul objet.Voir cette image (extraite de ce blog ):
Chaque fois que vous essayez d'accéder à une propriété dans un objet, JavaScript commence la recherche dans cet objet et continue avec son prototype, le prototype du prototype et ainsi de suite jusqu'à ce que la propriété soit rencontrée ou si elle
__proto__
contient la valeurnull
.Presque tous les objets sont des instances de
Object
, car ilObject.prototype
est le dernier de leur chaîne de prototypes. MaisObject.prototype
n'est pas une instance deObject
carObject.prototype.__proto__
détient la valeurnull
.Vous pouvez également créer un objet avec un
null
prototype comme celui-ci:Un tel objet est une meilleure carte (dictionnaire) d'un objet littéral, ce qui explique pourquoi ce modèle est parfois appelé le dict motif ( dict du dictionnaire).
Remarque: les objets littéraux créés à l'aide de
{}
sont des instances deObject
puisque({}).__proto__
est une référence àObject.prototype
.la source