Question 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 considérer la première déclaration comme une déclaration d'une méthode statique, et la deuxième déclaration comme une déclaration d'une méthode d'instance?


440
2017-10-28 03:59


origine


Réponses:


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

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

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

Considérez 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();

646
2017-10-28 04:08



Lorsque vous créez plus d'une instance de MyClass, vous n'avez toujours 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 économisent de la mémoire.

De plus, 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.


16
2017-09-02 10:08



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, j'ai gardé cette séquence. ****

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


7
2018-06-03 06:43



Oui, le premier est un static method aussi appelé class method, tandis que le second est un instance method.

Considérez les exemples suivants pour mieux le comprendre.

Dans ES5 

function Person(firstName, lastName) {
   this.firstName = firstName;
   this.lastName = lastName;
}

Person.isPerson = function(obj) {
   return obj.constructor === Person;
}

Person.prototype.sayHi = function() {
   return "Hi " + this.firstName;
}

Dans le code ci-dessus, isPerson est une méthode statique, tandis que sayHi est une méthode d'instance de Person.

Ci-dessous, comment créer un objet à partir de Person constructeur.

var aminu = new Person("Aminu", "Abubakar");

Utiliser la méthode statique isPerson.

Person.isPerson(aminu); // will return true

Utilisation de la méthode d'instance sayHi.

aminu.sayHi(); // will return "Hi Aminu"

En ES6

class Person {
   constructor(firstName, lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
   }

   static isPerson(obj) {
      return obj.constructor === Person;
   }

   sayHi() {
      return `Hi ${this.firstName}`;
   }
}

Regardez comment static mot-clé a été utilisé pour déclarer la méthode statique isPerson.

Pour créer un objet de Person classe.

const aminu = new Person("Aminu", "Abubakar");

Utiliser la méthode statique isPerson.

Person.isPerson(aminu); // will return true

Utilisation de la méthode d'instance sayHi.

aminu.sayHi(); // will return "Hi Aminu"

REMARQUE: Les deux exemples sont essentiellement les mêmes, le JavaScript reste un langage sans classe. le class introduit dans ES6 est avant tout un sucre syntaxique par rapport au modèle d’héritage existant basé sur un prototype.


1
2018-06-10 14:50