Essayer de comprendre le point des prototypes en JavaScript

je me rends compte que cela a été demandé des centaines de fois, cependant, je ne peux pas sembler saisir le concept de "pourquoi" les prototypes en JavaScript sont corrects, comme s'il s'agissait d'imiter des classes (Oui, je sais que JavaScript est un langage basé sur le prototypisme - j'en ai bien compris).

<!-Comme beaucoup d'autres personnes qui s'efforcent de faire du JavaScript un langage quotidien que j'utilise, je suis habitué au style de classe OOP régulier, car j'ai joué en Java (et utilisé des classes en ActionScript ainsi qu'en PHP). Cependant, while I penser je comprends le fonctionnement des prototypes, Je ne comprends pas pourquoi on en a besoin.

<!-Voici un exemple de script montrant comment je comprends actuellement les prototypes en JavaScript:

var Apple = function() {
    // An apple?
};

Apple.prototype.color = "red";

Apple.prototype.changeColor = function(new_color) {
    this.color = new_color;
};
Apple.prototype.getColor = function() {
    alert('color: '+this.color);
};

var apple1 = new Apple();
var apple2 = new Apple();
apple2.changeColor("green");
apple1.getColor();
apple2.getColor();

...J'avais supposé que peut - être le prototype signifiait qu'il partageait le même objet au lieu de simplement créer un nouvel objet à chaque fois - cependant, ce n'est évidemment pas le cas puisque apple1 et apple2 ont des couleurs différentes, encore (après avoir exécuté said script.)

puis je l'ai écrit dans ce qui est plus d'un script orienté objet:

var Apple = function() {
    this.color = "red";

    this.changeColor = function(new_color) {
        this.color = new_color;
    };
    this.getColor = function() {
        alert('color: '+this.color);
    };
};

var apple1 = new Apple();
var apple2 = new Apple();
apple2.changeColor("green");
apple1.getColor();
apple2.getColor();

Avec les mêmes résultats (comme prévu). ...Pourquoi ce dernier code n'est-il pas recommandé? Je n'ai aucun problème à utiliser des prototypes (en supposant que je les ai utilisés correctement), mais j'ai besoin de comprendre le concept de "pourquoi".

...Toute aide?

30
demandé sur clicheName 2011-01-30 07:37:38

2 réponses

...J'avais supposé que peut-être le prototype signifiait qu'elle partageait le même objet, au lieu de simplement créer un nouvel objet à chaque fois...

c'est le cas. Il y a un objet prototype qui est partagé entre toutes les instances créées à partir du constructeur.

...cependant, ce n'est évidemment pas le cas puisque apple1 et apple2 ont des couleurs différentes, toujours (après avoir exécuté ledit script).

pour certains types (par exemple Nombre, boolean, null, undefined, or string), lorsque vous changez une propriété qui existe sur l'objet prototype via this.color par exemple, pour créer un color propriété sur l'instance. Le prototype n'est pas affecté de sorte que les nouvelles instances auront la couleur par défaut définie dans le prototype.

si vous aviez mis à jour un membre d'un tableau ou un objet référencé par une propriété de l'objet prototype, le changement serait vu parmi toutes les instances.

...Pourquoi le dernier code n'est pas recommandé?

parce que vous construisez de nouvelles fonctions identiques avec la création de chaque nouvelle instance au lieu de partager une instance des fonctions via l'objet prototype.


développer un peu plus, je ferais remarquer que, lorsqu'une fonction est appelée en tant que constructeur, en utilisant le new mot clé this dans le constructeur la nouvelle instance. Donc, n'importe quelle propriété que vous ajoutez à this est ajoutés à l'instance.

var Apple = function() {
      // Here "this" is the object being constructed. As such, we're adding
      //   a property "rotten" to every instance created
    this.rotten = false;
};

   // adding a "color" property to the prototype object
Apple.prototype.color = "red";

   // set the property "color" on the instance to the value of "new_color"
Apple.prototype.changeColor = function(new_color) {
    this.color = new_color;
};
   // first check to see if this instance has its own "color" property. If so,
   //    use it. If not, look at the prototype object to see if it exists.
Apple.prototype.getColor = function() {
    alert('color: '+this.color);
};

// two new instances each have their own "rotten" property, and don't have a
//    "color" property. Both share the prototype object, so if "color" is 
//    requested, it will come from there
var apple1 = new Apple(); 
var apple2 = new Apple();

// This will add an "color" property to the "apple2" instance
apple2.changeColor("green");

// Doesn't have a "color" property, so it looks to the prototype object
apple1.getColor();

// Has a "color" property, so it uses that instead of the "color" on the prototype
apple2.getColor();
31
répondu user113716 2011-01-30 05:23:30

prototype vous permet d'ajouter des méthodes et des propriétés à une classe et il l'appliquera non seulement à la classe, mais aussi à toutes les instances objet courantes de cette classe.

5
répondu Crayon Violent 2011-01-30 04:45:58