Récemment, j'ai lu des informations sur l'utilisation des appels JavaScript dans MDC.
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/call
un exemple de l'exemple ci-dessous, je ne comprends toujours pas.
Pourquoi utilisent-ils l'héritage ici comme ça?
Prod_dept.prototype = new Product();
est-ce nécessaire? Parce qu'il y a un appel au super-constructeur dans
Prod_dept()
de toute façon, comme ça
Product.call
est-ce juste hors d'un comportement commun? Quand est-il préférable d'utiliser call pour le super-constructeur ou d'utiliser la chaîne de prototypes?
function Product(name, value){
this.name = name;
if(value >= 1000)
this.value = 999;
else
this.value = value;
}
function Prod_dept(name, value, dept){
this.dept = dept;
Product.call(this, name, value);
}
Prod_dept.prototype = new Product();
// since 5 is less than 1000, value is set
cheese = new Prod_dept("feta", 5, "food");
// since 5000 is above 1000, value will be 999
car = new Prod_dept("honda", 5000, "auto");
Merci d'avoir clarifié les choses
La réponse à la vraie question est que vous devez faire les deux:
Par conséquent, vous ne devez pas appeler le constructeur du parent lors de la configuration de l'héritage. Seulement lors de l'instanciation d'un objet qui hérite d'un autre.
La réponse de Chris Morgan est presque terminée, il manque un petit détail (propriété du constructeur). Permettez-moi de vous suggérer une méthode pour configurer l'héritage.
function extend(base, sub) {
// Avoid instantiating the base class just to setup inheritance
// Also, do a recursive merge of two prototypes, so we don't overwrite
// the existing prototype, but still maintain the inheritance chain
// Thanks to @ccnokes
var origProto = sub.prototype;
sub.prototype = Object.create(base.prototype);
for (var key in origProto) {
sub.prototype[key] = origProto[key];
}
// The constructor property was set wrong, let's fix it
Object.defineProperty(sub.prototype, 'constructor', {
enumerable: false,
value: sub
});
}
// Let's try this
function Animal(name) {
this.name = name;
}
Animal.prototype = {
sayMyName: function() {
console.log(this.getWordsToSay() + " " + this.name);
},
getWordsToSay: function() {
// Abstract
}
}
function Dog(name) {
// Call the parent's constructor
Animal.call(this, name);
}
Dog.prototype = {
getWordsToSay: function(){
return "Ruff Ruff";
}
}
// Setup the prototype chain the right way
extend(Animal, Dog);
// Here is where the Dog (and Animal) constructors are called
var dog = new Dog("Lassie");
dog.sayMyName(); // Outputs Ruff Ruff Lassie
console.log(dog instanceof Animal); // true
console.log(dog.constructor); // Dog
Voir mon article de blog pour encore plus de sucre syntaxique lors de la création de classes. http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html
Technique copiée à partir de Ext-JS et http://www.uselesspickles.com/class_library/ et d'un commentaire de https://stackoverflow.com/users/1397311/ccnokes
Le moyen idéal de le faire est de pas faire Prod_dept.prototype = new Product();
, parce que cela appelle le constructeur Product
. Donc, le moyen idéal est de le cloner sauf pour le constructeur, quelque chose comme ceci:
function Product(...) {
...
}
var tmp = function(){};
tmp.prototype = Product.prototype;
function Prod_dept(...) {
Product.call(this, ...);
}
Prod_dept.prototype = new tmp();
Prod_dept.prototype.constructor = Prod_dept;
Ensuite, le super constructeur est appelé au moment de la construction, ce que vous souhaitez, car vous pouvez également transmettre les paramètres.
Si vous regardez des éléments tels que la bibliothèque Google Closure, vous verrez que c'est ce qu'ils font.
Si vous avez effectué la programmation orientée objet en JavaScript, vous saurez que vous pouvez créer une classe de la manière suivante:
Person = function(id, name, age){
this.id = id;
this.name = name;
this.age = age;
alert('A new person has been accepted');
}
Jusqu'ici, notre personne de classe n'a que deux propriétés et nous allons lui donner quelques méthodes. Une façon propre de faire cela consiste à utiliser son objet "prototype". À partir de JavaScript 1.1, l’objet prototype a été introduit en JavaScript. Il s'agit d'un objet intégré qui simplifie le processus d'ajout de propriétés et de méthodes personnalisées à toutes les instances d'un objet. Ajoutons 2 méthodes à notre classe en utilisant son objet 'prototype' comme suit:
Person.prototype = {
/** wake person up */
wake_up: function() {
alert('I am awake');
},
/** retrieve person's age */
get_age: function() {
return this.age;
}
}
Maintenant nous avons défini notre classe personne. Et si nous voulions définir une autre classe appelée Manager, qui hérite de propriétés de Person. Il ne sert à rien de redéfinir à nouveau toutes ces propriétés lorsque nous définissons notre classe Manager, nous pouvons simplement la définir pour hériter de la classe Person. JavaScript n'a pas d'héritage intégré, mais nous pouvons utiliser une technique pour implémenter l'héritage de la manière suivante:
Inheritance_Manager = {};
// Nous créons une classe de gestionnaire d'héritage (le nom est arbitraire)
Donnons maintenant à notre classe d'héritage une méthode appelée extend qui prend les arguments baseClass et subClassas. Dans la méthode extend, nous allons créer une classe interne appelée fonction d'héritage héritage () {}. Nous utilisons cette classe interne pour éviter toute confusion entre les prototypes baseClass et subClass. Ensuite, nous faisons en sorte que le prototype de notre classe d’héritage pointe sur le prototype baseClass comme pour le code suivant: inheritance.prototype = baseClass. prototype; Ensuite, nous copions le prototype d'héritage dans le prototype de sous-classe comme suit: subClass.prototype = new inheritance (); La prochaine chose à faire est de spécifier le constructeur de notre sous-classe comme suit: subClass.prototype.constructor = subClass; Une fois que nous avons terminé avec notre prototype de sous-classe, nous pouvons spécifier les deux lignes de code suivantes pour définir des pointeurs de classe de base.
subClass.baseConstructor = baseClass;
subClass.superClass = baseClass.prototype;
Voici le code complet de notre fonction d’extension:
Inheritance_Manager.extend = function(subClass, baseClass) {
function inheritance() { }
inheritance.prototype = baseClass.prototype;
subClass.prototype = new inheritance();
subClass.prototype.constructor = subClass;
subClass.baseConstructor = baseClass;
subClass.superClass = baseClass.prototype;
}
Maintenant que nous avons implémenté notre héritage, nous pouvons commencer à l'utiliser pour étendre nos classes. Dans ce cas, nous allons étendre notre classe Person à une classe Manager comme suit:
Nous définissons la classe Manager
Manager = function(id, name, age, salary) {
Person.baseConstructor.call(this, id, name, age);
this.salary = salary;
alert('A manager has been registered.');
}
on en fait hériter la personne
Inheritance_Manager.extend(Manager, Person);
Si vous avez remarqué, nous venons d'appeler la méthode extend de notre classe Inheritance_Manager et de transmettre le gestionnaire de sous-classe dans notre cas, puis la personne de baseClass. Notez que la commande est très importante ici. Si vous les échangez, l'héritage ne fonctionnera pas comme prévu, voire pas du tout. Notez également que vous devrez spécifier cet héritage avant de pouvoir définir notre sous-classe. Définissons maintenant notre sous-classe:
Nous pouvons ajouter plus de méthodes comme celle ci-dessous. Notre classe de gestionnaires aura toujours les méthodes et les propriétés définies dans la classe de personne, car elle en hérite.
Manager.prototype.lead = function(){
alert('I am a good leader');
}
Maintenant, pour le tester, créons deux objets, un de la classe Person et un de la classe héritée Manager:
var p = new Person(1, 'Joe Tester', 26);
var pm = new Manager(1, 'Joe Tester', 26, '20.000');
N'hésitez pas à obtenir le code complet et d'autres commentaires à l'adresse suivante: http://www.cyberminds.co.uk/blog/articles/how-to-implement-javascript-inheritance.aspx