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
one
estObject.prototype
. - Le prototype de
two
estObject.prototype
. - Les attributs et les fonctions de
one
sont 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
one
estDate.prototype
. - Le prototype de
two
estObject.prototype
.- Donc l’objet
two
ne peut appeller aucunes des méthodes deDate
.
- Donc l’objet
- Le prototype de
three
estObject.prototype
.- Le prototype de
Date
est 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
one
estOne.prototype
. On peut aussi observer que le contructeur deOne
a pour prototypeFunction.prototype
. - Le prototype de
two
estObject.prototype
.- Donc l’objet
two
ne peut appeller aucunes méthodes deOne
- L’objet
two
possède une propriétéval
qui est une copie deone.val
au 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
one
estOne.prototype
. On peut aussi observer que le contructeur deOne
a pour prototypeFunction.prototype
. - Le prototype de
two
estObject.prototype
.- L’objet
two
possède pas la propriétéval
. - L’objet
two
ne possède une fonctionfn
qui est une copie deOne.prototype.fn
. - L’objet
two
ne possède pas le construteurcontructor
de 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
one
estObject.prototype
. - Le prototype de
two
estObject.prototype
.- Cette manière est stupide car
prototype
est considéré comme un attribut non pas comme l’accesseur duprototype
. - Logiquement aucun attribut ni aucune fonction de
one
n’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
one
estObject.prototype
. - Le prototype de
two
estthis.two.<prototype>
, c’est un prototype anonyme.- Tous les attributs et les fonctions de
one
sont accessible parTwo
. - Le
prototype
deTwo
est directement lié à l’instanceone
donc toutes modifications des attributs deone
sont 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
one
estOne.prototype
. - Le prototype de
two
estOne.prototype
.- Tous les attributs et les fonctions de
One
ont é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 :