JavaScript: Class.method vs. Class.prototype.method

Quelle est la différence entre les deux déclarations suivantes?

Class.method = function () { /* code */ } Class.prototype.method = function () { /* code using this.values */ } 

Est-il acceptable de penser à la première déclaration comme une déclaration d'une méthode statique, et la deuxième déclaration comme déclaration d'une méthode d'instance?

Oui, la première fonction n'a aucune relation avec une instance d'objet de cette fonction de constructeur , vous pouvez la considérer comme une «méthode statique» .

Dans les fonctions JavaScript, les objets de première classe , cela signifie que vous pouvez les traiter tout comme n'importe quel objet, dans ce cas, vous n'ajoutez qu'une propriété à l' objet fonction .

La deuxième fonction, au fur et à mesure que vous étendez le prototype de la fonction de constructeur, elle sera disponible pour toutes les instances d'objet créées avec le new mot-clé et le contexte dans cette fonction (le mot this clé this ) se référera à l'instance d'objet réelle où vous l'appelez .

Considérons cet exemple:

 // constructor function function MyClass () { var privateVariable; // private member only available within the constructor fn this.privilegedMethod = function () { // it can access private members //.. }; } // A 'static method', it's just like a normal function // it has no relation with any 'MyClass' object instance MyClass.staticMethod = function () {}; MyClass.prototype.publicMethod = function () { // the 'this' keyword refers to the object instance // you can access only 'privileged' and 'public' members }; var myObj = new MyClass(); // new object instance myObj.publicMethod(); MyClass.staticMethod(); 

Lorsque vous créez plus d'une instance de MyClass, vous n'aurez encore qu'une seule instance de publicMethod en mémoire, mais dans le cas de privilegedMethod, vous finirez par créer beaucoup d'instances et staticMethod n'a aucune relation avec une instance d'objet.

C'est pourquoi les prototypes enregistrent la mémoire.

En outre, si vous modifiez les propriétés de l'objet parent, la propriété correspondante de l'enfant n'a pas été modifiée, elle sera mise à jour.

Pour les apprenants visuels, lors de la définition de la fonction sans .prototype

 ExampleClass = function(){}; ExampleClass.method = function(customString){ console.log((customString !== undefined)? customString : "called from func def.");} ExampleClass.method(); // >> output: `called from func def.` var someInstance = new ExampleClass(); someInstance.method('Called from instance'); // >> error! `someInstance.method is not a function` 

Avec le même code, si .prototype est ajouté,

 ExampleClass.prototype.method = function(customString){ console.log((customString !== undefined)? customString : "called from func def.");} ExampleClass.method(); // > error! `ExampleClass.method is not a function.` var someInstance = new ExampleClass(); someInstance.method('Called from instance'); // > output: `Called from instance` 

Pour le rendre plus clair,

 ExampleClass = function(){}; ExampleClass.directM = function(){} //M for method ExampleClass.prototype.protoM = function(){} var instanceOfExample = new ExampleClass(); ExampleClass.directM(); ✓ works instanceOfExample.directM(); x Error! ExampleClass.protoM(); x Error! instanceOfExample.protoM(); ✓ works 

**** Remarque pour l'exemple ci-dessus, someInstance.method () ne sera pas exécuté comme,
ExampleClass.method () provoque une erreur et l'exécution ne peut pas continuer.
Mais pour des raisons d'illustration et de compréhension facile, j'ai gardé cette séquence. ****

Résultats générés à partir de la chrome developer console et JS Bin
Cliquez sur le lien jsbin ci-dessus pour parcourir le code.
Activez la section commentée avec ctrl + /