Javascript - Héritage & assign/extend
Une petite reflexion autour de l’héritage en Javascript ES5.
Assign/Extend
Example 1-1
// one
var one = { val: 'A', fn: function(){ return this.val; } };
this.one = one;
// two
var two = Object.assign({}, one);
this.two = two;
- Notes :
- Le prototype de
oneestObject.prototype. - Le prototype de
twoestObject.prototype. - Les attributs et les fonctions de
onesont disponible danstwo.
- Le prototype de
- Conclusion : pas de liaison directe entre les objets -> héritage ??
Example 1-2
// one
var one = new Date();
this.one = one;
// two
var two = Object.assign({}, one);
this.two = two;
// three
var three = Object.assign({}, Date.prototype);
this.three = three;
- Notes :
- Le prototype de
oneestDate.prototype. - Le prototype de
twoestObject.prototype.- Donc l’objet
twone peut appeller aucunes des méthodes deDate.
- Donc l’objet
- Le prototype de
threeestObject.prototype.- Le prototype de
Dateest un cas particulier car ces méthodes ne sont pas énumérables.
- Le prototype de
- Le prototype de
- Conclusion : pas d’héritage
Example 1-3
// one
function One(){
this.val = 'A';
}
One.prototype.fn = function(){
return this.val;
}
var one = new One()
this.one = one;
// two
var two = Object.assign({}, one);
this.two = two;
- Notes :
- Le prototype de
oneestOne.prototype. On peut aussi observer que le contructeur deOnea pour prototypeFunction.prototype. - Le prototype de
twoestObject.prototype.- Donc l’objet
twone peut appeller aucunes méthodes deOne - L’objet
twopossède une propriétévalqui est une copie deone.valau moment de l’assignation.
- Donc l’objet
- Le prototype de
- Conclusion : état étrange, copie partielle -> héritage ??
Exemple 1-4
// one
function One(){
this.val = 'A';
}
One.prototype.fn = function(){
return this.val;
}
var one = new One()
this.one = one;
// two
var two = Object.assign({}, One.prototype);
this.two = two;
- Notes :
- Le prototype de
oneestOne.prototype. On peut aussi observer que le contructeur deOnea pour prototypeFunction.prototype. - Le prototype de
twoestObject.prototype.- L’objet
twopossède pas la propriétéval. - L’objet
twone possède une fonctionfnqui est une copie deOne.prototype.fn. - L’objet
twone possède pas le construteurcontructorde l’objetOne.
- L’objet
- Le prototype de
- Conclusion : état étrange, copie partielle -> héritage ??
Prototype
Example 2-1
// one
var one = { val: 'A', fn: function(){ return this.val; } };
this.one = one;
// two
var two = {};
two.prototype = one;
this.two = two;
- Notes :
- Le prototype de
oneestObject.prototype. - Le prototype de
twoestObject.prototype.- Cette manière est stupide car
prototypeest considéré comme un attribut non pas comme l’accesseur duprototype. - Logiquement aucun attribut ni aucune fonction de
onen’est donc disponible surtwo.
- Cette manière est stupide car
- Le prototype de
- Conclusion : Stupide -> WRONG WAY
Example 2-2
// one
var one = { val: 'A', fn: function(){ return this.val; } };
this.one = one;
// two
function Two(){}
Two.prototype = one;
this.two = new Two();
one.val = 'N';
- Notes :
- Le prototype de
oneestObject.prototype. - Le prototype de
twoestthis.two.<prototype>, c’est un prototype anonyme.- Tous les attributs et les fonctions de
onesont accessible parTwo. - Le
prototypedeTwoest directement lié à l’instanceonedonc toutes modifications des attributs deonesont aussi appliqués àTwo. (ex:two.val === 'N'à la fin du script)
- Tous les attributs et les fonctions de
- Le prototype de
- Conclusion : liaison directe -> pas d’héritage, c’est une délégation directe avec une closure
Example 2-3
// one
function One(){
this.val = 'A';
}
One.prototype.fn = function(){
return this.val;
}
var one = new One()
this.one = one;
// two
function Two(){
One.call(this);
}
Two.prototype = Object.create(One.prototype);
Two.prototype.constructor = Two;
var two = new Two();
this.two = two;
- Notes :
- Le prototype de
oneestOne.prototype. - Le prototype de
twoestOne.prototype.- Tous les attributs et les fonctions de
Oneont été héritées parTwo.
- Tous les attributs et les fonctions de
- Le prototype de
- Conclusion : Héritage -> GOOD WAY
Conlusion
L’héritage classique (exemple 2-3) est un standard en OOP mais est-ce que l’héritage par concaténation (exemples 1-x) peut-il être réellement appellé héritage ? J’aurais tendance à dire que non à cause du coté aléatoire de cette technique.
Quelques articles intéressants :