2009-10-28 7 views
427

Quelle est la différence entre les deux déclarations suivantes?JavaScript: Class.method par rapport à Class.prototype.method

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

Est-il correct de penser à 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?

Répondre

630

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

Dans les fonctions JavaScript sont first-class objets, cela signifie que vous pouvez les traiter comme tout objet, dans ce cas, vous n'ajouter une propriété à l'objet de la fonction . La seconde fonction, comme vous étendez le prototype de la fonction constructeur, sera disponible pour toutes les instances d'objet créées avec le mot-clé new, et le contexte de cette fonction (le mot-clé this) fera référence à l'instance d'objet réelle où vous l'appelez.

Prenons 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(); 
+53

Ceci a été pris de: http://code.google.com/intl/es/speed/articles/optimizing-javascript.html Il est aussi important de dire que Si nous créons de nombreuses instances de 'MyClass', nous créons pour chaque instance une fonction' privilegedMethod'. Cependant 'publicMethod' est seulement construit une fois pour toutes les instances créées. – Menda

+13

Voici un lien mis à jour vers l'article mentionné dans le commentaire de Menda: https://developers.google.com/speed/articles/optimizing-javascript –

+1

Mais pourquoi Function.prototype.method == Function.method? – Raghavendra

15

Lorsque vous créez plus d'une instance de MyClass, vous n'ont toujours qu'une seule instance de publicMethod en mémoire mais en cas de privilegedMethod vous finirez par créer beaucoup de cas et staticMethod n'a aucune relation avec une instance d'objet. C'est pourquoi les prototypes économisent de la mémoire. C'est ce qui fait la différence entre les prototypes. 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.

5

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 code même 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 faire i t plus claire,

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 

**** pour noter l'exemple ci-dessus, someInstance.method() ne sera pas exécuté comme,
ExampleClass.method() provoque une erreur & exécution ne peut pas continuer.
Mais pour l'amour d'illustration & compréhension facile, je l'ai gardé cette séquence. ****

Les résultats générés par chrome developer console & JS Bin
Cliquez sur le lien ci-dessus jsbin à l'étape dans le code.
bascule a commenté la section avec ctrl + /

Questions connexes