Quelle est la différence entre les deux déclarations suivantes?
Class.method = function () { /* code */ }
Class.prototype.method = function () { /* code using this.values */ }
Peut-on considérer la première instruction comme une déclaration d'une méthode statique et la seconde comme une déclaration d'une méthode d'instance?
Oui, la première fonction n'a pas de relation avec une instance d'objet de celle-ci fonction constructeur , vous pouvez la considérer comme une 'méthode statique' .
En JavaScript, les fonctions sont des objets de première classe , vous pouvez donc les traiter comme n'importe quel objet. Dans ce cas, vous ajoutez uniquement une propriété à le fonction function .
La seconde fonction, à mesure que vous développez le prototype de fonction constructeur, sera disponible pour toutes les instances d'objet créées avec le mot-clé new
, ainsi que pour le contexte de cette fonction (le this
= mot-clé) fera référence à 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 plusieurs instances de MyClass, vous n'avez toujours qu'une seule instance de publicMethod en mémoire, mais dans le cas de privilegedMethod, vous créez un grand nombre d'instances et staticMethod n'a pas de relation avec une instance d'objet.
C'est pourquoi les prototypes économisent de la mémoire.
De même, si vous modifiez les propriétés de l'objet parent, si 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 que ce soit 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 conservé cette séquence. ****
Résultats générés à partir de _chrome developer console
_ & JS Bin
Cliquez sur le lien jsbin ci-dessus pour parcourir le code.
Basculer la section commentée avec ctrl+/
Oui, le premier est un static method
également appelé class method
, tandis que le second est un instance method
.
Considérez les exemples suivants pour le comprendre plus en détail.
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
.
Vous trouverez ci-dessous comment créer un objet à partir du constructeur Person
.
var aminu = new Person("Aminu", "Abubakar");
Utilisation de 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"
dans 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
class.
const aminu = new Person("Aminu", "Abubakar");
Utilisation de 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"
NOTE: Les deux exemples sont essentiellement les mêmes, JavaScript reste un langage sans classes. La class
introduite dans ES6 est avant tout un sucre syntaxique par rapport au modèle d'héritage existant basé sur un prototype.