98 votes

Javascript quand utiliser des prototypes

J'aimerais comprendre quand il est approprié d'utiliser le prototype des méthodes en js. Devraient-ils toujours être utilisé (ou il y a des cas où leur utilisation n'est pas recommandée et/ou encourt une pénalité de performances)? Dans la recherche autour de ce site sur des méthodes communes pour namespacing en js il semble que la plupart d'utiliser un non-prototype de mise en œuvre: il suffit à l'aide d'un objet, ou un objet de fonction pour encapsuler un espace de noms. Venant d'une classe de langue sur son difficile de ne pas essayer de tracer des parallèles et pense que les prototypes sont comme des "classes" et les implémentations de l'espace de noms que j'ai mentionnés sont comme des méthodes statiques. Une clarification serait génial.

138voto

Daniel Earwicker Points 63298

Les Prototypes sont d'une optimisation.

Un excellent exemple de l'utilisation du bien est la bibliothèque jQuery. Chaque fois que vous obtenez un objet jQuery en utilisant $('.someClass'), cet objet a des dizaines de "méthodes". La bibliothèque pourrait atteindre que par le renvoi d'un objet:

return {
   show: function() { ... },
   hide: function() { ... },
   css: function() { ... },
   animate: function() { ... },
   // etc...
};

Mais cela signifierait que chaque objet jQuery dans la mémoire de dizaines de nommé emplacements contenant les mêmes méthodes, plus et plus.

Au lieu de cela, ces méthodes sont définies sur un prototype et tous les objets jQuery "hériter" ce prototype, afin d'obtenir toutes ces méthodes à un très faible coût d'exécution.

Une grande importance comment jQuery est juste, c'est que ce qui est caché au programmeur. Il est considéré purement une optimisation, non pas comme quelque chose que vous avez à vous soucier lorsque vous utilisez la bibliothèque.

Le problème avec le JavaScript, c'est que nu constructeur fonctions nécessitent l'appelant n'oubliez pas de les préfixer avec new ou sinon, en général, ils ne fonctionnent pas. Il n'y a pas de bonne raison pour cela. jQuery est juste en cachant ce non-sens derrière une fonction ordinaire, $, de sorte que vous n'avez pas de soins de la façon dont les objets sont mis en œuvre.

De sorte que vous pouvez facilement créer un objet avec un certain prototype, ECMAScript 5 comprend une fonction standard Object.create. Une version très simplifiée de il devrait ressembler à ceci:

Object.create = function(prototype) {
    var Type = function () {};
    Type.prototype = prototype;
    return new Type();
};

Simplement, il prend soin de la douleur de l'écriture d'une fonction de constructeur et de son appel avec new.

Quand voulez-vous éviter les prototypes?

Une utile comparaison avec les langages à objets comme Java et C#. Ces deux types d'héritage:

  • l'interface de l'héritage, où vous implement un interface tels que la classe possède ses propres mise en œuvre pour chaque membre de l'interface.
  • la mise en œuvre de l'héritage, où vous extend un class qui fournit des implémentations par défaut de certaines méthodes.

En JavaScript, prototype de l'héritage est une sorte de mise en oeuvre de l'héritage. Donc, dans ces situations où l' (en C# ou Java) vous aurait obtenu à partir d'une classe de base pour gagner le comportement par défaut, ce qui permet ensuite d'apporter de petites modifications par remplacements, puis en JavaScript, l'héritage par prototype de sens.

Toutefois, si vous êtes dans une situation où vous avez utilisé des interfaces en C# ou en Java, alors vous n'avez pas besoin tout particulier pour le langage JavaScript. Il n'est pas nécessaire de déclarer explicitement quelque chose qui représente l'interface, et pas besoin de marquer des objets comme la "mise en œuvre" de l'interface:

var duck = {
    quack: function() { ... }
};

duck.quack(); // we're satisfied it's a duck!

En d'autres termes, si chaque "type" d'objet a sa propre définition de la "méthodes", alors il n'existe pas de valeur dans hériter d'un prototype. Après, cela dépend du nombre d'instances que vous allouer de chaque type. Mais dans beaucoup de conceptions modulaires, il n'y a qu'une seule instance d'un type donné.

Et en fait, il a été suggéré par de nombreuses personnes que la mise en œuvre de l'héritage est le mal. C'est, si il ya des opérations courantes pour un type, alors c'est peut-être plus clair si ils ne sont pas mis dans une base/super classe, mais sont simplement exposés comme des fonctions dans certains module, à qui vous transmettez l'objet(s) que vous souhaitez utiliser.

47voto

akellehe Points 3183

Vous devez utiliser des prototypes si vous souhaitez déclarer une méthode "non statique" de l'objet.

 var myObject = function () {

};

myObject.prototype.getA = function (){
  alert("A");
};

myObject.getB = function (){
  alert("B");
};

myObject.getB();  // This works fine

myObject.getA();  // Error!

var myPrototypeCopy = new myObject();
myPrototypeCopy.getA();  // This works, too.
 

17voto

hellatan Points 1013

L'une des raisons pour utiliser le haut- prototype objet est si vous serez de la duplication d'un objet à plusieurs reprises qui partagent les mêmes fonctionnalités. Par la fixation de méthodes pour le prototype, vous pouvez économiser sur la duplication des méthodes en cours de création par chaque new de l'instance. Mais lorsque vous attachez une méthode pour l' prototype, toutes les instances ont accès à ces méthodes.

Disons que vous avez une base Car() classe/objet.

function Car() {
    // do some car stuff
}

ensuite, vous créez plusieurs Car() des cas.

var volvo = new Car(),
    saab = new Car();

Maintenant, vous savez que chaque voiture aura besoin de rouler, tourner, etc. Au lieu de fixer une méthode directement à l' Car() de la classe (ce qui prend de la mémoire pour chaque instance créée), vous pouvez joindre les méthodes pour le prototype de la place (de la création de l'méthodes qu'une seule fois), donc de donner accès à ces méthodes à la fois à la nouvelle - volvo et saab.

// just mapping for less typing
Car.fn = Car.prototype;

Car.fn.drive = function () {
    console.log("they see me rollin'");
};
Car.fn.honk = function () {
    console.log("HONK!!!");
}

volvo.honk();
// => HONK!!!
saab.drive();
// => they see me rollin'

12voto

Pointy Points 172438

Mettre des fonctions sur un prototype d'un objet lorsque vous allez créer beaucoup de copies d'un type particulier d'objet et ils ont tous besoin de partager des comportements communs. En faisant ainsi, vous allez économiser de la mémoire par le fait d'avoir une seule copie de chaque fonction, mais ce n'est que le simple profit.

Changement de méthodes sur des objets prototypes, ou l'ajout de méthodes, change instantanément de la nature de toutes les instances du type correspondant(s).

Maintenant exactement pourquoi vous devriez faire toutes ces choses est principalement fonction de votre propre conception de l'application, et le genre de choses que vous devez faire dans le code côté client. (Une toute autre histoire, le code sera à l'intérieur d'un serveur; beaucoup plus facile d'imaginer de faire à plus grande échelle "OO" de code.)

3voto

Anil Namde Points 2291

Si je l'explique dans la classe de base de terme, alors la Personne est classe, marcher() est la méthode de Prototype. Alors à pied() aura son existence qu'après vous instancier un nouvel objet avec cette.

Donc, si vous voulez créer une copie de l'objet comme Personne u peut créer de nombreux utilisateurs Prototype est la bonne solution car il permet d'économiser de la mémoire par le partage ou d'hériter de la même copie de la fonction pour chaque objet en mémoire.

Alors que statique n'est pas que une grande aide dans un tel scénario.

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

// its instance method and can access objects data data 
Person.prototype.walk = function(){
alert("person has started walking.");
}
// its like static method
Person.ProcessPerson = function(Person p){
alert("Persons name is = " + p.name);
}

var userOne = new Person();
var userTwo = new Person();

//Call instance methods
userOne.walk();

//Call static methods
Person.ProcessPerson(userTwo);

Donc, avec ce son de plus comme une méthode d'instance. L'objet de l'approche, c'est comme des méthodes Statiques.

https://developer.mozilla.org/en/Introduction_to_Object-Oriented_JavaScript

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X