Définir des méthodes via un prototype ou utiliser ceci dans le constructeur - vraiment une différence de performance?
En JavaScript, nous avons deux façons de faire une "classe" et de lui donner des fonctions publiques.
Méthode 1:
function MyClass() {
var privateInstanceVariable = 'foo';
this.myFunc = function() { alert(privateInstanceVariable ); }
}
Méthode 2:
function MyClass() { }
MyClass.prototype.myFunc = function() {
alert("I can't use private instance variables. :(");
}
J'ai lu de nombreuses fois, les gens en disant: que l'aide de la Méthode 2 est plus efficace que toutes les instances partagent la même copie de la fonction plutôt que de l'obtention de leur propre. La définition de fonctions via le prototype a un énorme inconvénient cependant, il est impossible d'avoir privé les variables d'instance.
Même si, en théorie, à l'aide de la Méthode 1 donne à chaque instance d'un objet de sa propre copie de la fonction (et donc utilise de manière de plus de mémoire, pour ne pas mentionner le temps nécessaire pour les allocations) - est-ce que ce qui se passe réellement dans la pratique? Il semble comme une optimisation des navigateurs web pourrait facilement faire est de reconnaître que ceci est extrêmement commun, et ont en fait toutes les instances de l'objet de référence la même copie de fonctions définies par l'intermédiaire de ces "fonctions constructeur". Ensuite, il ne pourrait que donner un exemple de sa propre copie de la fonction si elle est explicitement modifié par la suite.
Toute réflexion - ou, mieux encore, expérience du monde réel - sur les différences de performances entre les deux, serait extrêmement utile.
source d'informationauteur MgSam
Vous devez vous connecter pour publier un commentaire.
Voir http://jsperf.com/prototype-vs-this
La déclaration des méthodes via le prototype est plus rapide, mais si oui ou non cela est pertinent, c'est discutable.
Si vous avez un goulot d'étranglement des performances de votre application, il est peu probable que cela, à moins que vous arrive d'être l'instanciation de 10000+ objets sur chaque étape de l'arbitraire de l'animation, par exemple.
Si la performance est un problème grave, et que vous souhaitez micro-optimiser, alors je suggère de déclarer via prototype. Sinon, il suffit d'utiliser le modèle qui fait le plus de sens pour vous.
Je vais ajouter que, en JavaScript, il existe une convention de préfixer les propriétés qui sont destinés à être considérées comme privées, avec un trait de soulignement (par exemple
_process()
). La plupart des développeurs de comprendre et d'éviter ces propriétés, sauf s'ils sont prêts à abandonner le contrat social, mais dans ce cas, vous pourriez aussi bien ne pas les satisfaire. Ce que je veux dire, c'est que: vous n'avez probablement pas vraiment besoin de vrai variables privées...Dans la nouvelle version de Chrome, cette.la méthode est d'environ 20% plus rapide que le prototype.la méthode, mais la création d'un nouvel objet est encore plus lent.
Si vous pouvez réutiliser l'objet au lieu de toujours créer un nouveau, ce peut être de 50% à 90% plus rapide que la création de nouveaux objets. En Plus l'avantage de ne collecte des ordures, ce qui est énorme:
http://jsperf.com/prototype-vs-this/59
Il ne fait une différence lorsque vous créez un grand nombre de cas. Autrement, les performances de l'appel de la fonction membre est exactement le même dans les deux cas.
J'ai créé un cas de test sur jsperf pour le démontrer:
http://jsperf.com/prototype-vs-this/10
Vous pourriez ne pas avoir pensé à cela, mais en mettant la méthode directement sur l'objet est fait de mieux dans un sens:
Cependant, la différence de vitesse est presque négligeable. En plus de cela, mettre une méthode sur un prototype est meilleure dans les deux plus efficaces façons:
Comme Jacques a dit, cette différence peut être importante si vous êtes l'instanciation des milliers d'instances d'une classe.
Cela dit, je peux certainement imaginer un moteur JavaScript qui reconnaît que la fonction que vous attachez à chaque objet ne change pas entre les instances et donc ne conserve qu'une copie de la fonction dans la mémoire, avec toutes les méthodes d'instance de pointage à la fonction partagée. En fait, il semble que Firefox est en train de faire certains d'optimisation particulière comme cela, mais Chrome ne l'est pas.
De CÔTÉ:
Vous avez raison, il est impossible d'accéder à des variables d'instance privé à partir de l'intérieur des méthodes sur des prototypes. Donc je suppose que la question que vous devez vous poser est: aimez-vous être capable de faire des variables d'instance véritablement privé sur utilisant l'héritage et le prototypage? Personnellement, je pense que faire des variables de vraiment privé n'est pas si important et qu'il suffit d'utiliser le trait de soulignement préfixe (par exemple, "cette._myVar") pour signifier que même si la variable est public, il doit être considéré comme privé. Cela dit, dans l'ES6, apparemment, il y a un moyen d'avoir à la fois des deux mondes!
En bref, utilisez la méthode 2 pour la création de propriétés/méthodes que toutes les instances de partager. Ceux-ci vont être "global" et tout changement pourra être répercuté sur toutes les instances. Utilisez la méthode 1 pour la création de l'instance spécifique de propriétés/méthodes.
Je voudrais avoir une meilleure référence, mais pour l'instant, jetez un oeil à cette. Vous pouvez voir comment j'ai utilisé les deux méthodes dans le même projet à des fins différentes.
Espère que cette aide. 🙂