Question __proto__ VS. prototype en JavaScript


Cette figure montre encore que chaque objet a un prototype. Constructeur   la fonction Foo a aussi sa propre __proto__ qui est Function.prototype,   et qui à son tour fait également référence via son __proto__ propriété à nouveau à   le Object.prototype. Ainsi, répétez, Foo.prototype est juste un explicite   propriété de Foo qui se réfère au prototype d'objets b et c.

var b = new Foo(20);
var c = new Foo(30);

Quelles sont les différences entre __proto__ et prototype Propriétés?

enter image description here

La figure est tirée de ici.


599
2018-03-31 21:13


origine


Réponses:


__proto__ est l'objet réel utilisé dans la chaîne de recherche pour résoudre les méthodes, etc. prototype est l'objet qui est utilisé pour construire __proto__ lorsque vous créez un objet avec new:

( new Foo ).__proto__ === Foo.prototype;
( new Foo ).prototype === undefined;

571
2018-03-31 21:16



prototype est une propriété d'un objet Function. C'est le prototype d'objets construits par cette fonction.

__proto__ est la propriété interne d'un objet, pointant vers son prototype. Les normes actuelles fournissent un équivalent Object.getPrototypeOf(O) méthode, bien que de facto standard __proto__ est plus rapide.

Tu peux trouver instanceof relations en comparant une fonction de prototype à un objet __proto__ chaîne, et vous pouvez rompre ces relations en changeant prototype.

function Point(x, y) {
    this.x = x;
    this.y = y;
}

var myPoint = new Point();

// the following are all true
myPoint.__proto__ == Point.prototype
myPoint.__proto__.__proto__ == Object.prototype
myPoint instanceof Point;
myPoint instanceof Object;

Ici Point est une fonction constructeur, elle construit un objet (structure de données) procéduralement. myPoint est un objet construit par Point() alors Point.prototype est enregistré dans myPoint.__proto__ à ce moment-là.


278
2018-03-31 21:20



La propriété de prototype est créée lorsqu'une fonction est déclarée.

Par exemple:

 function Person(dob){
    this.dob = dob
 }; 

La propriété Person.prototype est créée en interne une fois que vous avez déclaré la fonction above. De nombreuses propriétés peuvent être ajoutées au Person.prototype qui sont partagées par les instances Person créées à l'aide de la nouvelle Person ().

// adds a new method age to the Person.prototype Object.
Person.prototype.age = function(){return date-dob}; 

Il est à noter que Person.prototype est un Object littéral par défaut (il peut être modifié au besoin).

Chaque instance créée en utilisant new Person () a un __proto__ propriété qui pointe vers le prototype Person. C'est la chaîne que l'on traverse pour trouver une propriété d'un objet particulier.

var person1 = new Person(somedate);
var person2 = new Person(somedate);

crée 2 instances de Person, ces 2 objets peuvent appeler la propriété age de Person.prototype en tant que person1.age, person2.age.

Dans l'image ci-dessus, vous pouvez voir que Foo est un objet fonction et donc il a un __proto__ lien vers le Function.prototype qui à son tour est une instance de Object et a un __proto__ lien vers Object.prototype. Le lien proto se termine ici avec __proto__ dans le Object.prototype pointant vers null.

Tout objet peut avoir accès à toutes les propriétés de sa chaîne proto comme liées par __proto__ , formant ainsi la base de l'héritage prototypique.

__proto__ n'est pas un moyen standard d'accéder à la chaîne du prototype, l'approche standard mais similaire est d'utiliser Object.getPrototypeOf (obj).

Ci-dessous le code pour instanceof l'opérateur donne une meilleure compréhension:

objet instanceof Retours de l'opérateur de classe true lorsqu'un objet est une instance d'une classe, plus précisément si Class.prototype est trouvé dans la chaîne proto de cet objet alors l'objet est une instance de cette classe.

function instanceOf(Func){
var obj = this;
while(obj !== null){
    if(Object.getPrototypeOf(obj) === Func.prototype)
        return true;
    obj = Object.getPrototypeOf(obj);
}
return false;
}

La méthode ci-dessus peut être appelée comme: instanceOf.call(object,Class)qui renvoie true si l'objet est instance de Class.


91
2017-08-10 15:27



Une bonne façon d'y penser est ...

prototype est utilisé par constructor() les fonctions. Ça aurait vraiment dû s'appeler quelque chose comme, "prototypeToInstall", puisque c'est ce que c'est.

et __proto__ est ce "prototype installé" sur un objet (qui a été créé / installé sur l'objet à partir de constructor() fonction)


56
2018-05-30 16:26



Prototype VS. __proto__ VS. [[Prototype]]

Lors de la création d'une fonction, un objet de propriété appelé prototype est créé automatiquement (vous ne l'avez pas créé vous-même) et est attaché à l'objet fonction (le constructor).
  Remarque: Ce nouveau prototype object pointe également vers l'objet JavaScript natif ou a un lien interne-privé vers celui-ci.

Exemple:

function Foo () {
    this.name = 'John Doe';
}

// Foo has an object property called prototype.
// prototype was created automatically when we declared the function Foo.
Foo.hasOwnProperty('prototype'); // true

// Now, we can assign properties and methods to it:
Foo.prototype.myName = function () {
    return 'My name is ' + this.name;
}

Si vous allez créer un nouvel objet à partir de Foo en utilisant le new mot clé, vous créez essentiellement (entre autres choses) un nouvel objet qui a un lien interne ou privé au prototype de la fonction Foo nous avons discuté plus tôt:

var b = new Foo();

b.[[Prototype]] === Foo.prototype  // true


le privé lien avec l'objet de cette fonction appelé prototype double crochets ou juste [[Prototype]]. De nombreux navigateurs nous fournissent un Publique lien à celui qui a appelé __proto__!

Pour être plus précis, __proto__ est en fait un fonction getter qui appartiennent à l'objet JavaScript natif. Il renvoie le lien de prototype interne-privé de quel que soit le this la liaison est (renvoie la [[Prototype]] de b):

b.__proto__ === Foo.prototype // true

Il est à noter que le démarrage de ECMAScript5, vous pouvez également utiliser le getPrototypeOf méthode pour obtenir le lien privé interne:

Object.getPrototypeOf(b) === b.__proto__ // true


REMARQUE: cette réponse n'a pas l'intention de couvrir tout le processus de création de nouveaux objets ou de nouveaux constructeurs, mais d'aider à mieux comprendre ce qui est __proto__, prototype et [[Prototype]] et comment ça marche.


38
2017-09-23 12:49



Pour expliquer, créons une fonction

 function a (name) {
  this.name = name;
 }

Lorsque JavaScript exécute ce code, il ajoute prototype propriété à a, prototype La propriété est un objet avec deux propriétés:

  1. constructor
  2. __proto__

Alors quand on fait

a.prototype ça revient

     constructor: a  // function definition
    __proto__: Object

Maintenant comme vous pouvez le voir constructor n'est rien d'autre que la fonction a se et __proto__ pointe vers le niveau racine Object de JavaScript.

Voyons ce qui se passe quand nous utilisons a fonctionner avec new mot-clé.

var b = new a ('JavaScript');

Lorsque JavaScript exécute ce code, il fait 4 choses:

  1. Il crée un nouvel objet, un objet vide // {}
  2. Ça crée __proto__ sur b et le fait pointer vers a.prototype alors b.__proto__ === a.prototype
  3. Il exécute a.prototype.constructor (qui est la définition de la fonction a ) avec l'objet nouvellement créé (créé à l'étape 1) comme contexte (ceci), d'où le name propriété transmise en tant que 'JavaScript' (qui est ajouté à this) est ajouté à l'objet nouvellement créé.
  4. Il retourne l'objet nouvellement créé dans (créé à l'étape # 1) donc var b est affecté à l'objet nouvellement créé.

Maintenant, si nous ajoutons a.prototype.car = "BMW" et fait b.car, la sortie "BMW" apparaît.

c'est parce que lorsque JavaScript a exécuté ce code, il a cherché carpropriété sur b, il n'a pas trouvé alors JavaScript utilisé b.__proto__ (qui a été fait pour pointer vers 'a.prototype' à l'étape 2) et trouve car propriété donc retour "BMW".


37
2018-02-02 12:50



Pour le rendre un peu clair en plus des bonnes réponses ci-dessus:

function Person(name){
    this.name = name
 }; 

var eve = new Person("Eve");

eve.__proto__ == Person.prototype //true

eve.prototype  //undefined

Instances avoir __proto__, Des classes avoir prototype.


21
2017-10-07 19:26