javascript_tome_xvii - Prototype
ECMA définit le prototype comme ceci : « object that provides shared properties for other objects » Le PROTOTYPE d’un objet est la propriété (méthode) native de cet objet qui stocke toutes les valeurs par défaut des propriétés et méthodes natives de cet objet en tant que parent, quand la propriété ou la méthode n’est pas définie dans l’instance. Le prototype est initialement vide au moment de la construction de l’objet. Pour définir des propriétés pour cet objet ou lui en ajouter d’autres, il suffit de les ajouter via son prototype, et automatiquement ces nouvelles propriétés seront partagées avec toutes les instances de cet objet. Bien entendu on peut aussi ajouter directement de nouvelles propriétés à l’objet ou l’une ou l’autre de ces instances, tout simplement en omettant le mot prototype dans la définition de la nouvelle propriété, mais dans ce cas cette nouvelle propriété de l’objet ne sera pas membre du prototype de l’objet et donc ne sera pas héritable (ou partageable avec les instances), donc strictement personnel à ce constructeur ou cette instance.
ECMA définit le prototype comme ceci :
« object that provides shared properties for other objects »
Le PROTOTYPE d’un objet est la propriété (méthode) native de cet objet qui stocke toutes les valeurs par défaut des propriétés et méthodes natives de cet objet en tant que parent, quand la propriété ou la méthode n’est pas définie dans l’instance. Le prototype est initialement vide au moment de la construction de l’objet. Pour définir des propriétés pour cet objet ou lui en ajouter d’autres, il suffit de les ajouter via son prototype, et automatiquement ces nouvelles propriétés seront partagées avec toutes les instances de cet objet. Bien entendu on peut aussi ajouter directement de nouvelles propriétés à l’objet ou l’une ou l’autre de ces instances, tout simplement en omettant le mot prototype dans la définition de la nouvelle propriété, mais dans ce cas cette nouvelle propriété de l’objet ne sera pas membre du prototype de l’objet et donc ne sera pas héritable (ou partageable avec les instances), donc strictement personnel à ce constructeur ou cette instance.
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
J.B. Dadet DIASOLUKA Luyalu Nzoyifuanga<br />
JAVASCRIPT (ProgrammationInternet)VOL. V<br />
+243 - 851278216 - 899508675 - 991239212 - 902263541 - 813572818<br />
La dernière révision de ce texte est disponible sur CD.<br />
CHAPITRE 7 : LE PROTOTYPE :<br />
ECMA définit le prototype comme ceci :<br />
« object that provides shared properties for other objects »<br />
Le PROTOTYPE d’un objet est la propriété (méthode) native de cet objet<br />
qui stocke toutes les valeurs par défaut des propriétés et méthodes<br />
natives de cet objet en tant que parent, quand la propriété ou la méthode<br />
n’est pas définie dans l’instance. Le prototype est initialement<br />
vide au moment de la construction de l’objet. Pour définir des propriétés<br />
pour cet objet ou lui en ajouter d’autres, il suffit de les ajouter via son<br />
prototype, et automatiquement ces nouvelles propriétés seront partagées<br />
avec toutes les instances de cet objet. Bien entendu on peut aussi<br />
ajouter directement de nouvelles propriétés à l’objet ou l’une ou l’autre<br />
de ces instances, tout simplement en omettant le mot prototype<br />
dans la définition de la nouvelle propriété, mais dans ce cas cette nouvelle<br />
propriété de l’objet ne sera pas membre du prototype de l’objet et<br />
donc ne sera pas héritable (ou partageable avec les instances), donc<br />
strictement personnel à ce constructeur ou cette instance.<br />
<br />
cl=console.log<br />
obj_Const=function(pnom,pdaten){<br />
this.K=1000*3600*24*365.2475;<br />
this.nom=pnom;<br />
this.daten=pdaten;<br />
this.age=function(){<br />
return((new Date()-pdaten)/this.K)<br />
}<br />
}<br />
i=new obj_Const("André",new Date("August 1953 11"));<br />
for(i in obj_Const.prototype)cl(i);<br />
cl("Age = "+i.age());<br />
cl("AJOUT DE PROTOTYPES")<br />
obj_Const.prototype.riche=true; // Ajout via prototype<br />
obj_Const.sage=false; // Ajout direct (ne se répand pas)
J.D.B. DIASOLUKA Nz. Luyalu<br />
JavaScript Tome-V<br />
obj_Const.prototype.nbfemmes=35; // Ajout via prototype<br />
obj_Const.prototype.polygame=function(){ // ---"---<br />
if(this.nbfemmes>1)return true;<br />
else return false;<br />
};<br />
cl("LISTE DES PROPRIÉTÉS")<br />
cl("i.nom="+i.nom);<br />
cl("i.age="+i.age());<br />
cl("i.sage="+i.sage);<br />
cl("i.riche="+i.riche);<br />
cl("i.nbfemmes="+i.nbfemmes)<br />
cl("i.polygame="+i.polygame())<br />
cl("\nLES PROTOTYPES AJOUTÉS")<br />
for(i in obj_Const.prototype)<br />
cl("==> "+i+" = "+obj_Const.prototype[i]);<br />
cl(obj_Const.prototype);<br />
cl(i.prototype);<br />
cl(obj_Const.prototype.constructor);<br />
cl(obj_Const.__proto__.constructor);<br />
cl("obj_Const.prototype.constructor.length = "+<br />
obj_Const.prototype.constructor.length);<br />
<br />
Exécution :<br />
Age = 64.3917223791744<br />
AJOUT DE PROTOTYPES<br />
LISTE DES PROPRIÉTÉS<br />
i.nom=André<br />
i.age=64.39172237923778<br />
i.sage=undefined<br />
i.riche=true<br />
i.nbfemmes=35<br />
i.polygame=true<br />
LES PROTOTYPES AJOUTÉS<br />
==> riche = true<br />
==> nbfemmes = 35<br />
==> polygame = function(){ // ---"---<br />
if(this.nbfemmes>1)return true;<br />
else return false;<br />
}<br />
Object { riche: true, nbfemmes: 35, polygame:<br />
obj_Const.prototype.polygame(), … }<br />
undefined<br />
function obj_Const()<br />
function Function()<br />
obj_Const.prototype.constructor.length = 2<br />
Le <strong>Prototype</strong> 2 / 21 mercredi, 7. novembre 2018
J.D.B. DIASOLUKA Nz. Luyalu<br />
JavaScript Tome-V<br />
Ajout d’un prototype à un objet :<br />
<br />
"use strict";<br />
Array.prototype.remVal = function(val) {<br />
console.log(["Louis", "Morena", "Keriyza", "Louis"]);<br />
for (var i = 0, l=this.length; i < l; i++) {<br />
if (this[i] === val) {<br />
this.splice(i, 1);<br />
i--;<br />
}<br />
}<br />
return this;<br />
}<br />
console.log(["Louis", "Morena", "Keriyza", "Louis"].remVal(2));<br />
<br />
Exécution :<br />
(4) ["Louis", "Morena", "Keriyza", "Louis"]<br />
(2) ["Morena", "Keriyza"]<br />
Pour différents modes de création d’objet :<br />
<br />
"use strict";<br />
/* 1 */<br />
console.log(<br />
"***AVEC CONSTRUCTEUR, var dObj = function(){}"<br />
)<br />
var dObj = function(){}<br />
var iObj1 = new dObj();<br />
//// TypeError: iObj.prototype is undefined<br />
// iObj1.prototype.fprot1= _=><br />
// console.log("iObj1.prototype.fprot1");<br />
iObj1.__proto__.fprot2 = _=><br />
console.log("1a. Ds iObj1.__proto__.fprot2");<br />
iObj1.fprot2();<br />
iObj1.fprot3= function(){<br />
Le <strong>Prototype</strong> 3 / 21 mercredi, 7. novembre 2018
J.D.B. DIASOLUKA Nz. Luyalu<br />
JavaScript Tome-V<br />
console.log("1b. Ds iObj1.fprot3");<br />
}<br />
iObj1.fprot3();<br />
/* 2 */<br />
console.log(<br />
"***AVEC NEW OBJECT(), var iObj2 = new Object()"<br />
)<br />
var iObj2 = new Object();<br />
//// TypeError: iObj2.prototype is undefined<br />
// iObj2.prototype.fprot4= _=><br />
// console.log("iObj2.prototype.fprot4");<br />
iObj2.__proto__.fprot5 = _=><br />
console.log("2a. Ds iObj2.__proto__.fprot5");<br />
iObj2.fprot5();<br />
iObj2.fprot6= function(){<br />
console.log("2b. Ds iObj2.fprot6");<br />
}<br />
iObj2.fprot6();<br />
/* 3 */<br />
console.log(<br />
"***AVEC LITTEREL D'OBJET (HASH), var iObj3 = {}"<br />
)<br />
var iObj3 = {};<br />
//// TypeError: iObj3.prototype is undefined<br />
// iObj3.prototype.fprot7= _=><br />
// console.log("iObj3.prototype.fprot7");<br />
iObj3.__proto__.fprot8 = _=><br />
console.log("3a. Ds iObj3.__proto__.fprot8");<br />
iObj3.fprot8();<br />
// Exécute la ligne ci-dessus<br />
iObj3.__proto__.fprot8();<br />
// Exécute aussi la ligne ci-dessus<br />
// Définition directe de propriété<br />
iObj3.fprot9 = function() {<br />
Le <strong>Prototype</strong> 4 / 21 mercredi, 7. novembre 2018
J.D.B. DIASOLUKA Nz. Luyalu<br />
JavaScript Tome-V<br />
console.log("3b. Ds iObj3.fprot9");<br />
}<br />
iObj3.fprot9();<br />
/* 4 */<br />
console.log(<br />
"***AVEC OBJECT.CREATE, let pObj = _ => {}"<br />
)<br />
let pObj = _ => {}<br />
let iObj = Object.create(pObj);<br />
pObj.fprot10 = _ =><br />
console.log("4a. Ds pObj.fprot10 de pObj");<br />
iObj.fprot10(); // Appelée à partir de iObj vs pObj.<br />
// pObj.prototype.fprot11 = _ =><br />
// console.log("4b. Ds pObj.prototype.fprot11")<br />
// TypeError:<br />
// pObj.prototype is undefined test.html:89:3<br />
pObj.prototype = _ =><br />
console.log("4b. Ds pObj.prototype");<br />
iObj.prototype();<br />
// Le prototype ici est une fonction.<br />
// On peut l’enrichir plus tard pour le<br />
// convertir en objet ordinaire !<br />
pObj.prototype.fprot12 = _ =><br />
console.log("4c. Ds pObj.prototype.fprot12");<br />
iObj.prototype.fprot12();<br />
// Le prototype est aussi un objet.<br />
alert(iObj.prototype);<br />
alert(iObj.prototype.fprot12);<br />
console.log(Object.getOwnPropertyDescriptors(pObj))<br />
// Object {<br />
// fprot10: {…},<br />
// prototype: {…},<br />
// length: {…},<br />
// name: {…}<br />
// }<br />
// {…}<br />
// fprot10: Object {<br />
// configurable: true<br />
// enumerable: true<br />
// value: function fprot10():<br />
Le <strong>Prototype</strong> 5 / 21 mercredi, 7. novembre 2018
J.D.B. DIASOLUKA Nz. Luyalu<br />
JavaScript Tome-V<br />
// _ => console.log("4a. Ds pObj.fprot10 de pObj")<br />
// writable: true<br />
// : Object {<br />
//<br />
//<br />
fprot5: function fprot5():<br />
_=> console.log("2a. Ds iObj2.__proto__.fprot5"),<br />
// fprot8: function fprot8():<br />
// _=> console.log("3a. Ds iObj3.__proto__.fprot8"),<br />
// constructor: function Object(),<br />
// …<br />
// }<br />
//<br />
// length: Object {<br />
// value: 1,<br />
// writable: false,<br />
// enumerable: false,<br />
// configurable: true,<br />
// : Object {<br />
// fprot5: function fprot5():<br />
// _=> console.log("2a. Ds iObj2.__proto__.fprot5"),<br />
// fprot8: function fprot8():<br />
// _=> console.log("3a. Ds iObj3.__proto__.fprot8"),<br />
// constructor: function Object(),<br />
// …<br />
// }<br />
//<br />
// name: Object {<br />
// value: "pObj",<br />
// writable: false,<br />
// enumerable: false,<br />
// configurable: true,<br />
// : Object {<br />
// fprot5: function fprot5():<br />
// _=> console.log("2a. Ds iObj2.__proto__.fprot5"),<br />
// fprot8: function fprot8():<br />
// _=> console.log("3a. Ds iObj3.__proto__.fprot8"),<br />
// constructor: function Object(),<br />
// …<br />
// }<br />
//<br />
// prototype: Object {<br />
// value: _ => console.log("4b. Ds pObj.prototype")<br />
// writable: true,<br />
// enumerable: true,<br />
// configurable: true,<br />
// : Object {<br />
// fprot5: function fprot5():<br />
// _=> console.log("2a. Ds iObj2.__proto__.fprot5"),<br />
// fprot8: function fprot8():<br />
// _=> console.log("3a. Ds iObj3.__proto__.fprot8"),<br />
// constructor: function Object(),<br />
Le <strong>Prototype</strong> 6 / 21 mercredi, 7. novembre 2018
J.D.B. DIASOLUKA Nz. Luyalu<br />
JavaScript Tome-V<br />
// …<br />
// }<br />
//<br />
//<br />
//<br />
__proto__: Object {<br />
fprot5: function fprot5():<br />
// _=> console.log("2a. Ds iObj2.__proto__.fprot5"),<br />
// fprot8: function fprot8():<br />
// _=> console.log("3a. Ds iObj3.__proto__.fprot8"),<br />
// constructor: function Object(),<br />
// …<br />
// }<br />
//<br />
// __proto__: Object {<br />
// value: ƒ,<br />
// writable: true,<br />
// enumerable: true,<br />
// configurable: true<br />
// }<br />
// test.html:107:3<br />
console.log(Object.getOwnPropertyDescriptors(iObj))<br />
// Object { }<br />
// __proto__: Object {<br />
// fprot5: function fprot5():<br />
// _=> console.log("2a. Ds iObj2.__proto__.fprot5"),<br />
// fprot8: function fprot8():<br />
// _=> console.log("3a. Ds iObj3.__proto__.fprot8"),<br />
// constructor: function Object(),<br />
// …<br />
// }<br />
// test.html:179:3<br />
<br />
Exécution :<br />
***AVEC CONSTRUCTEUR, var dObj = function(){}<br />
test.html:4:1<br />
1a. Ds iObj1.__proto__.fprot2 test.html:16:7<br />
1b. Ds iObj1.fprot3 test.html:21:7<br />
***AVEC NEW OBJECT(), var iObj2 = new Object()<br />
test.html:28:1<br />
2a. Ds iObj2.__proto__.fprot5 test.html:38:7<br />
2b. Ds iObj2.fprot6 test.html:43:7<br />
Le <strong>Prototype</strong> 7 / 21 mercredi, 7. novembre 2018
J.D.B. DIASOLUKA Nz. Luyalu<br />
JavaScript Tome-V<br />
***AVEC LITTEREL D'OBJET (HASH), var iObj3 = {}<br />
test.html:51:1<br />
3a. Ds iObj3.__proto__.fprot8 test.html:61:7<br />
3b. Ds iObj3.fprot9 test.html:71:7<br />
***AVEC OBJECT.CREATE, let pObj = _ => {}<br />
test.html:78:1<br />
4a. Ds pObj.fprot10 de pObj test.html:86:8<br />
4b. Ds pObj.prototype test.html:95:8<br />
4c. Ds pObj.prototype.fprot12 test.html:100:8<br />
Object {<br />
fprot10: {…},<br />
prototype: {…},<br />
length: {…},<br />
name: {…}<br />
}<br />
test.html:107:3<br />
Object { } test.html:179:3<br />
La chaîne du prototype :<br />
JavaScript est un langage basé sur le prototype (prototype-based language).<br />
On préfère même dire que c’est un système basé sur la délégation<br />
(delegation-based system), c’est-à-dire que chaque objet a une<br />
chaîne de prototype (prototype chain) :<br />
Quand vous tentez d’accéder à une propriété ou méthode d’un objet<br />
(en cours de création ou d’instanciation ou une instance d’objet), il se<br />
passe ceci : 1. Si cette propriété existe comme telle dans l’objet en soi,<br />
elle est récupérée ; 2. Si cette propriété n’existe pas en soi dans cet objet,<br />
elle est cherchée dan le prototype de l’object ; le prototype est un<br />
objet délégué (delegate object) c’est-à-dire que la recherche de la propriété<br />
est déléguée à l’objet « prototype » (prototype object) qui est<br />
une propriété de l’objet manipulé. Si l’objet prototype possède la propriété<br />
cherchée, celle-ci est récupéré, sinon elle est éventuellement<br />
cherchée dans le prototype du prototype, 3... Ainsi de suite la recherche<br />
se poursuit (chaîne du prototype) jusqu’à l’objet racine souvent le Object<br />
(avec « O » majuscule) et éventuellement son prototype (prototype<br />
Le <strong>Prototype</strong> 8 / 21 mercredi, 7. novembre 2018
J.D.B. DIASOLUKA Nz. Luyalu<br />
JavaScript Tome-V<br />
de l’objet racine =root prototype) souvent le prototype de Object « Object.prototype<br />
».<br />
"use strict";<br />
// Constructeur AVEC SA PROPRE toString().<br />
function dObj1() {<br />
this.toString=_=> "... dans dObj1.toString()";<br />
return("Un Objet retourne sa propre copie.")<br />
}<br />
console.log(dObj1);<br />
// function dObj1()<br />
console.log(""+dObj1);<br />
/* function dObj1() {<br />
this.toString=_=> "... dans dObj1.toString()";<br />
return("Un Objet retourne sa propre copie.")<br />
}<br />
*/<br />
let iObj1=new dObj1();<br />
// iObj1 n'a pas de toString() propre<br />
// => chaîne de prototype vers son constructeur<br />
// dObj1.toString() ou dObj1.prototype.toString()<br />
console.log(iObj1);<br />
// Object { toString: toString() }<br />
console.log(""+iObj1);<br />
// ... dans dObj1.toString()<br />
console.log("*AAAAA* "+dObj1);<br />
/* *AAAAA* function dObj1() {<br />
this.toString=_=> "... dans dObj1.toString()";<br />
return("Un Objet retourne sa propre copie.")<br />
}<br />
*/<br />
console.log("*AAAAA* "+dObj1.__proto__.toString());<br />
// *AAAAA* function () {}<br />
console.log("*BBBBB* "+iObj1);<br />
// *BBBBB* Object { toString: toString() }<br />
console.log("*DDDDD* "+iObj1.__proto__.toString());<br />
// *DDDDD* [object Object]<br />
// Constructeur SANS toString() PROPRE<br />
function dObj2() {<br />
// Pas de propriété toString() propre<br />
}<br />
Le <strong>Prototype</strong> 9 / 21 mercredi, 7. novembre 2018
J.D.B. DIASOLUKA Nz. Luyalu<br />
console.log(dObj2);<br />
// function dObj2()<br />
console.log(""+dObj2);<br />
/* function dObj2() {<br />
// Pas de propriété toString() propre<br />
}<br />
*/<br />
JavaScript Tome-V<br />
let iObj2=new dObj2();<br />
// iObj2 n'a pas de toString() propre<br />
// ni son constructeur => chaîne de prototype<br />
// vers toString du constructeur du constructeur<br />
// ou du prototype du constructeur du constructeur.<br />
console.log(iObj2);<br />
// bject { }<br />
console.log(""+iObj2);<br />
// [object Object]<br />
console.log("*AAAAA* "+dObj2);<br />
/* *AAAAA* function dObj2() {<br />
// Pas de propriété toString() propre<br />
}<br />
*/<br />
console.log("*AAAAA* "+dObj2.__proto__.toString());<br />
// *AAAAA* function () {}<br />
console.log("*BBBBB* "+iObj2);<br />
// *BBBBB* [object Object]<br />
console.log("*DDDDD* "+iObj2.__proto__.toString());<br />
// *DDDDD* [object Object]<br />
// Constructeur SANS toString() PROPRE,<br />
// mais ayant toString() dans son prototype.<br />
function dObj3() {<br />
}<br />
dObj3.prototype.toString=_=> console.log("toString de prototype")<br />
// toString de prototype<br />
console.log(dObj3);<br />
// function dObj3()<br />
console.log(""+dObj3);<br />
// function dObj3() {}<br />
let iObj3=new dObj3();<br />
// iObj3 n'a pas de toString() propre<br />
// ni son constructeur => chaîne de prototype<br />
// vers toString du constructeur du constructeur<br />
Le <strong>Prototype</strong> 10 / 21 mercredi, 7. novembre 2018
J.D.B. DIASOLUKA Nz. Luyalu<br />
JavaScript Tome-V<br />
// ou du prototype du constructeur du constructeur.<br />
console.log(iObj3);<br />
// Object { }<br />
console.log(""+iObj3);<br />
// undefined<br />
console.log("*AAAAA* "+dObj3);<br />
// *AAAAA* function dObj3() {}<br />
console.log("*AAAAA* "+dObj3.__proto__.toString());<br />
// *AAAAA* function () {}<br />
console.log("*BBBBB* "+iObj3);<br />
// *BBBBB* undefined<br />
console.log("*DDDDD* "+iObj3.__proto__.toString());<br />
// *DDDDD* undefined<br />
// APPEL DE CONSTRUCTEUR ET OBJET COMME FONCTIONS ORDINAIRES<br />
// TypeError: this is undefined test.html:4:8<br />
// dObj1 file:///K:/DADET/PROGS/test.html:4:8<br />
// file:///K:/DADET/PROGS/test.html:121:10<br />
///////// dObj1();<br />
//<br />
// TypeError: iObj1 is not a function test.html:124:10<br />
///////// iObj1();<br />
// CHRONOLOGIE DES EXÉCUTIONS AVEC MAXTHON:<br />
/*<br />
2018-02-25 15:33:08.364 test.html:8<br />
function dObj1() {<br />
this.toString=_=> "... dans dObj1.toString()";<br />
return("Un Objet retourne sa propre copie.")<br />
}<br />
2018-02-25 15:33:08.386 test.html:10<br />
function dObj1() {<br />
this.toString=_=> "... dans dObj1.toString()";<br />
return("Un Objet retourne sa propre copie.")<br />
}<br />
2018-02-25 15:33:08.386 test.html:21<br />
dObj1 {}<br />
2018-02-25 15:33:08.388 test.html:23<br />
... dans dObj1.toString()<br />
2018-02-25 15:33:08.388 test.html:26<br />
*AAAAA* function dObj1() {<br />
this.toString=_=> "... dans dObj1.toString()";<br />
return("Un Objet retourne sa propre copie.")<br />
}<br />
2018-02-25 15:33:08.388 test.html:33<br />
Le <strong>Prototype</strong> 11 / 21 mercredi, 7. novembre 2018
J.D.B. DIASOLUKA Nz. Luyalu<br />
*AAAAA* function () {}<br />
2018-02-25 15:33:08.388 test.html:36<br />
*BBBBB* ... dans dObj1.toString()<br />
2018-02-25 15:33:08.389 test.html:39<br />
*DDDDD* [object Object]<br />
2018-02-25 15:33:08.389 test.html:48<br />
dObj2() {<br />
// Pas de propriété toString() propre<br />
}<br />
2018-02-25 15:33:08.389 test.html:50<br />
function dObj2() {<br />
// Pas de propriété toString() propre<br />
}<br />
2018-02-25 15:33:08.389 test.html:61<br />
dObj2 {}<br />
2018-02-25 15:33:08.389 test.html:63<br />
[object Object]<br />
2018-02-25 15:33:08.389 test.html:66<br />
*AAAAA* function dObj2() {<br />
// Pas de propriété toString() propre<br />
}<br />
2018-02-25 15:33:08.390 test.html:72<br />
*AAAAA* function () {}<br />
2018-02-25 15:33:08.390 test.html:75<br />
*BBBBB* [object Object]<br />
2018-02-25 15:33:08.390 test.html:78<br />
*DDDDD* [object Object]<br />
2018-02-25 15:33:08.390 test.html:89<br />
dObj3() {}<br />
2018-02-25 15:33:08.390 test.html:91<br />
function dObj3() {}<br />
2018-02-25 15:33:08.390 test.html:99<br />
dObj3 {}<br />
2018-02-25 15:33:08.390 test.html:86<br />
toString de prototype<br />
2018-02-25 15:33:08.390 test.html:101<br />
undefined<br />
2018-02-25 15:33:08.390 test.html:104<br />
*AAAAA* function dObj3() {}<br />
2018-02-25 15:33:08.390 test.html:107<br />
*AAAAA* function () {}<br />
2018-02-25 15:33:08.391 test.html:86<br />
toString de prototype<br />
2018-02-25 15:33:08.391 test.html:110<br />
*BBBBB* undefined<br />
2018-02-25 15:33:08.391 test.html:86<br />
toString de prototype<br />
2018-02-25 15:33:08.391 test.html:113<br />
*DDDDD* undefined<br />
*/<br />
JavaScript Tome-V<br />
Le <strong>Prototype</strong> 12 / 21 mercredi, 7. novembre 2018
J.D.B. DIASOLUKA Nz. Luyalu<br />
<br />
JavaScript Tome-V<br />
CHROLOLOGIE DES EXÉCUTIONS AVCE FIREFOX :<br />
function dObj1()<br />
test.html:8:4<br />
function dObj1() {<br />
this.toString=_=> "... dans dObj1.toString()";<br />
return("Un Objet retourne sa propre copie.")<br />
} test.html:10:4<br />
Object { toString: toString() }<br />
test.html:21:4<br />
... dans dObj1.toString() test.html:23:4<br />
*AAAAA* function dObj1() {<br />
this.toString=_=> "... dans dObj1.toString()";<br />
return("Un Objet retourne sa propre copie.")<br />
} test.html:26:4<br />
*AAAAA* function () {<br />
} test.html:33:4<br />
*BBBBB* ... dans dObj1.toString()<br />
test.html:36:4<br />
*DDDDD* [object Object]<br />
test.html:39:4<br />
function dObj2()<br />
test.html:48:4<br />
function dObj2() {<br />
// Pas de propriété toString() propre<br />
} test.html:50:4<br />
Object { } test.html:61:4<br />
[object Object]<br />
test.html:63:4<br />
*AAAAA* function dObj2() {<br />
// Pas de propriété toString() propre<br />
} test.html:66:4<br />
*AAAAA* function () {<br />
} test.html:72:4<br />
*BBBBB* [object Object]<br />
test.html:75:4<br />
*DDDDD* [object Object]<br />
test.html:78:4<br />
function dObj3()<br />
test.html:89:4<br />
function dObj3() {<br />
} test.html:91:4<br />
Object { } test.html:99:4<br />
toString de prototype<br />
test.html:86:33<br />
undefined<br />
test.html:101:4<br />
*AAAAA* function dObj3() {<br />
} test.html:104:4<br />
*AAAAA* function () {<br />
} test.html:107:4<br />
toString de prototype<br />
test.html:86:33<br />
*BBBBB* undefined<br />
test.html:110:4<br />
toString de prototype<br />
test.html:86:33<br />
*DDDDD* undefined<br />
test.html:113:4<br />
Le prototype est comme une banque des propriétés par défaut de l’objet<br />
et surtout ses instances, pouvant donc être partagées avec les descendants<br />
(instances) de cet objet. Mais en plus des propriétés du proto-<br />
Le <strong>Prototype</strong> 13 / 21 mercredi, 7. novembre 2018
J.D.B. DIASOLUKA Nz. Luyalu<br />
JavaScript Tome-V<br />
type, l’objet peut avoir ses propriétés propres non stockées dans le prototype<br />
(propriétés non membres de son prototype).<br />
En d’autres termes :<br />
Toute propriété du prototype d’un objet appartient aussi à cet objet, mais<br />
certaines propriétés de l’objet ne sont pas nécessairement propriétés de<br />
son prototype (et donc sont non héritables), une instance d’objet pouvant<br />
aussi avoir des « ownProperties ».<br />
Implications de la chaîne de prototype :<br />
Considérons cet objet parent (constructeur) :<br />
let oParent = function(p){<br />
}<br />
// objet vide avec prototype implicite, vide.<br />
Créons deux instances de cet objet parent oParent, comme suit :<br />
let iObjet1 = new oParent();<br />
let iObjet2 = new oParent();<br />
Ajoutons une propriété dans le prototype du constructeur<br />
oParent.prototype.distance={<br />
par_avion:"1000 km",<br />
par_route:"2500km"<br />
}<br />
Les deux instances iObjet1 et iObjet2 héritent automatiquement de<br />
cette nouvelle propriété définie dans le prototype de l’objet parent.<br />
Par exemple, les deux instances afficheront distance = 1000 km :<br />
console.log(iObjet1.distance.par_avion);<br />
console.log(iObjet2.distance.par_avion);<br />
console.log(iObjet1.distance.par_route);<br />
console.log(iObjet2.distance.par_route);<br />
Le <strong>Prototype</strong> 14 / 21 mercredi, 7. novembre 2018
J.D.B. DIASOLUKA Nz. Luyalu<br />
JavaScript Tome-V<br />
Si nous redéfinissons la distance pour l’instance par exemple celle de<br />
iObjet2, comme ceci :<br />
iObjet2.distance.par_route = "3500 km";<br />
Comme iObjet2 n’a pas la propriété distance parmi ses OwnProperties,<br />
l’ordinateur considérera que c’est la propriété distance du prototype du<br />
parent (constructeur) que l’on a voulu modifier, et modifiera donc ce<br />
prototype du constructeur, et l’effet se manifestera à toutes les instances<br />
du constructeur.<br />
Ainsi donc, en tentant d’afficher la distance par_route de l’instance iObjet1,<br />
c’est la distance redéfinie pour l’objet iObjet2 (3500 km) qui sera affichée.<br />
Si on avait défini la distance comme une propriété-objet comme ceci,<br />
elle serait automatiquement considérée comme propriété propre (faisant<br />
partie seulement) de iObjet2 :<br />
iObjet2.distance={<br />
par_avion : "1750 km",<br />
par_route : "3500 km"<br />
}<br />
console.log(iObjet1.distance.par_avion); // 1000 km<br />
console.log(iObjet2.distance.par_avion); // 1750 km<br />
console.log(iObjet1.distance.par_route); // 3500 km<br />
console.log(iObjet2.distance.par_route); // 3500 km<br />
Le tout donne :<br />
"use strict";<br />
let oParent = function(p){<br />
}<br />
// objet vide avec prototype implicite, vide.<br />
let iObjet1 = new oParent();<br />
let iObjet2 = new oParent();<br />
oParent.prototype.distance={<br />
par_avion:"1000 km",<br />
par_route:"2500km"<br />
}<br />
console.log(iObjet1.distance.par_avion); // 1000 km<br />
Le <strong>Prototype</strong> 15 / 21 mercredi, 7. novembre 2018
J.D.B. DIASOLUKA Nz. Luyalu<br />
JavaScript Tome-V<br />
console.log(iObjet2.distance.par_avion); // 1000 km<br />
console.log(iObjet1.distance.par_route); // 2500km<br />
console.log(iObjet2.distance.par_route); // 2500km<br />
iObjet2.distance.par_route = "3500 km";<br />
console.log(iObjet1.distance.par_avion); // 1000 km<br />
console.log(iObjet2.distance.par_avion); // 1000 km<br />
console.log(iObjet1.distance.par_route); // 3500 km<br />
console.log(iObjet2.distance.par_route); // 3500 km<br />
iObjet2.distance={<br />
par_avion : "1750 km",<br />
par_route : "3500 km"<br />
}<br />
console.log(iObjet1.distance.par_avion); // 1000 km<br />
console.log(iObjet2.distance.par_avion); // 1000 km<br />
console.log(iObjet1.distance.par_route); // 3500 km<br />
console.log(iObjet2.distance.par_route); // 3500 km<br />
<br />
Dans la dissection ci-dessous nous voyons que le prototype dépend du<br />
fait que notre constructeur ait des paramètres formels ou pas, et s’il<br />
comporte des « this » ou pas, peu importe s’il est instancié. Un constructeur<br />
sans « this » est une fonction ordinaire, mais bien entendu une<br />
fonction est bel et bien un objet).<br />
I. Sans paramètres formels avec ou sans « this » et même avec un<br />
corps vide :<br />
<br />
'use strict';<br />
// Fonction ordinaire<br />
function dObj(){<br />
var fdObj = function(){<br />
return("Insiding dObj.fdObj")<br />
}<br />
}<br />
console.log(dObj)<br />
<br />
Le <strong>Prototype</strong> 16 / 21 mercredi, 7. novembre 2018
J.D.B. DIASOLUKA Nz. Luyalu<br />
JavaScript Tome-V<br />
Nous voyons dans la console de FireFox que le prototype implicite (par<br />
défaut) de notre fonction est l’objet objet, et celui de son parent est<br />
[aussi] une fonction.<br />
function dObj()<br />
dObj()<br />
length: 0<br />
name: "dObj"<br />
prototype: Object { … }<br />
__proto__: function ()<br />
En déroulant ses éléments dans la console, nous obtenons ceci :<br />
Dans le prototype par défaut de notre fonction dObj() celle-ci est bel et<br />
bien un/le constructeur.<br />
dObj()<br />
length: 0<br />
name: "dObj"<br />
prototype: {…}<br />
constructor: function dObj()<br />
__proto__: Object { … }<br />
__proto__: ()<br />
apply: function apply()<br />
arguments: null<br />
bind: function bind()<br />
call: function call()<br />
caller: null<br />
constructor: function Function()<br />
isGenerator: function isGenerator()<br />
length: 0<br />
name: ""<br />
toSource: function toSource()<br />
toString: function toString()<br />
Symbol(Symbol.hasInstance): undefined<br />
__proto__: Object { … }<br />
Son constructeur est un objet [__proto__ du prototype de dObj :<br />
« dObj() - prototype: (...) - __proto__ »] est Object.<br />
En déroulant ce __proto__ nous voyons que le constructeur de ce prototype<br />
est la fonction Object() que nous savons être un objet (l’objet<br />
parent de tous les autres objets). Nous voyons qu’il n’est pas affiché le<br />
__proto__ (parent) de Object : l’objet objet n’a pas de parent, il n’est fils<br />
de rien..<br />
Le <strong>Prototype</strong> 17 / 21 mercredi, 7. novembre 2018
J.D.B. DIASOLUKA Nz. Luyalu<br />
JavaScript Tome-V<br />
prototype: Object { … }<br />
prototype: {…}<br />
constructor: function dObj()<br />
__proto__: {…}<br />
__defineGetter__: function __defineGetter__()<br />
__defineSetter__: function __defineSetter__()<br />
__lookupGetter__: function __lookupGetter__()<br />
__lookupSetter__: function __lookupSetter__()<br />
constructor: function Object()<br />
hasOwnProperty: function hasOwnProperty()<br />
is<strong>Prototype</strong>Of: function is<strong>Prototype</strong>Of()<br />
propertyIsEnumerable: function propertyIsEnumerable()<br />
toLocaleString: function toLocaleString()<br />
toSource: function toSource()<br />
toString: function toString()<br />
unwatch: function unwatch()<br />
valueOf: function valueOf()<br />
watch: function watch()<br />
Nous pouvons aussi y voir les autres propriétés du prototype de cet<br />
Object parent du prototype de dObj :<br />
function __defineGetter__()<br />
defineGetter__(), function __defineSetter__()<br />
defineSetter__(),<br />
function __lookupGetter__()<br />
lookupGetter__(), function __lookupSetter__()<br />
lookupSetter__(),<br />
constructor: function Object()<br />
function hasOwnProperty(), function is<strong>Prototype</strong>Of(), function<br />
propertyIsEnumerable(), function toLocaleString(),<br />
function toSource(), function toString(), function un-<br />
watch(), function valueOf(), function watch()<br />
Nous avons vu là, le prototype du constructeur du prototype implicite<br />
de notre fonction dObj() (qui est en fait aussi un objet). Voyons maintenant<br />
le prototype du constructeur de notre fonction dObj() : « dObj() -<br />
__proto__ » :<br />
Nous y voyons que le constructeur de notre fonction est une fonction<br />
(__proto__: function ()).<br />
Déroulons ce prototype du parent :<br />
Nous voyons que le constructeur de ce parent est une fonction, la<br />
fonction Function (avec « F » majuscule, qui est aussi bien entendu un<br />
objet, le constructeur [pas « parent »] de l’objet Object et de la fonction<br />
Functiont). Ce constructeur parent a un __proto__ (comprenez « prototype<br />
du parent » ou tout simplement « le parent »), comme on peut le<br />
Le <strong>Prototype</strong> 18 / 21 mercredi, 7. novembre 2018
J.D.B. DIASOLUKA Nz. Luyalu<br />
JavaScript Tome-V<br />
voir ci-dessous, qui est l’objet Object, parent de tous les objets y<br />
compris les fonctions (comme on le constate ici).<br />
Mais attention, ne confondez pas l’objet générique « Object » et l’objet<br />
global « window » qu’ont peut nommer ou pas et qui renferme entre autres<br />
les propriétés suivantes : Infinity , NaN , undefined , eval() , isFinite()<br />
, isNaN() , parseFloat() , parseInt() , decodeURI() , decodeURIComponent()<br />
, encodeURI() , encodeURIComponent() , Math , JSON , Reflect , Object() ,<br />
Function() , Boolean() , Number() , String() , Symbol() , Array() , Float32Array()<br />
, Float64Array() , Int8Array() , Int16Array() , Int32Array() , Uint8Array()<br />
, Uint8ClampedArray() , Uint16Array() , Uint32Array() , ArrayBuffer() , Data-<br />
View() , Date() , RegExp() , Set() , WeakSet() , Map() , WeakMap() , Proxy() ,<br />
Promise() , Error() , SyntaxError() , RangeError() , TypeError() , ReferenceError()<br />
, URIError() , EvalError().<br />
Il n’est pas nécessaire de retenir par coeur cette liste partielle (mais il<br />
faut connaître leur existence), vous pouvez obtenir la liste exhaustive à<br />
la console du navigateur en tapant « Object.getOwnPropertyNames(window)<br />
». Baidu en liste 591, Maxthon 753, UC Browser 771, Torch<br />
781, FireFox 794, Yandex 807, Google Chrome 808, Vivaldi 809, Opera<br />
813, Brave 814, UR Brower 831,...<br />
Toutes les propriétés de l’objet global window sont disponibles (=accesibles)<br />
directement de partout sans préfixer du nom d’objet « window ».<br />
Dans l’espace global (càd en dehors de toute fonction), « this » est<br />
l’alias de « window ».<br />
__proto__: ()<br />
apply: function apply()<br />
arguments: null<br />
bind: function bind()<br />
call: function call()<br />
caller: null<br />
constructor: function Function()<br />
isGenerator: function isGenerator()<br />
length: 0<br />
name: ""<br />
toSource: function toSource()<br />
toString: function toString()<br />
Symbol(Symbol.hasInstance): undefined<br />
__proto__: Object { … }<br />
En déroulant le constructeur « function Function » nous pouvons voir<br />
ses propriétés dont encore un __proto__ qui est une fonction :<br />
Le <strong>Prototype</strong> 19 / 21 mercredi, 7. novembre 2018
J.D.B. DIASOLUKA Nz. Luyalu<br />
constructor: Function()<br />
length: 1<br />
name: "Function"<br />
__proto__: function ()<br />
JavaScript Tome-V<br />
En déroulant ce __proto__: function() nous obtenons :<br />
__proto__: ()<br />
apply: function apply()<br />
arguments: null<br />
bind: function bind()<br />
call: function call()<br />
caller: null<br />
constructor: function Function()<br />
isGenerator: function isGenerator()<br />
length: 0<br />
name: ""<br />
toSource: function toSource()<br />
toString: function toString()<br />
Symbol(Symbol.hasInstance): undefined<br />
__proto__: Object { … }<br />
Les propriétés de cet objet Function sont donc :<br />
Méthodes<br />
:<br />
function apply(), function bind(), function call(), function<br />
Function(), function isGenerator(), function to-<br />
Source(), function toString(),<br />
Propriétés :<br />
arguments: null, caller: null, length: 0, name: "", Symbol(Symbol.hasInstance):<br />
undefined<br />
En déroulant ce __proto __ : Object {...} nous tombons de nouveau sur<br />
l’objet Object qui n’a pas de __proto__ donc pas de parent (pas de<br />
constructeur).<br />
II. Avec des paramètres formels avec ou sans « this » :<br />
Notre fonction dObj() n’a aucun prototype même pas le prototype par<br />
défaut, donc aucune propriété initiale. Mais il a un __proto__ qui est le<br />
même constructeur que la forme sans paramètres.<br />
Kinshasa, le 7 novembre 2018 (1:00 pm).<br />
Le <strong>Prototype</strong> 20 / 21 mercredi, 7. novembre 2018
J.D.B. DIASOLUKA Nz. Luyalu<br />
JavaScript Tome-V<br />
Mots-clés :<br />
chaîne du prototype, JavaScript, prototype, prototype-based language,<br />
délégation, delegation-based system, prototype chain, objet<br />
délégué, delegate object, objet prototype, prototype object, objet<br />
racine, root prototype, Object.prototype<br />
DIASOLUKANz.Luyalu<br />
Docteur en Médecine, Chirurgie & Accouchements (1977),<br />
CNOM : 0866 - Spécialiste en ophtalmologie (1980)<br />
Études humanités : Scientifique - Mathématiques & Physique.<br />
Informaticien-amateur, Programmeur et WebMaster.<br />
Chercheur indépendant, autonome et autofinancé, bénévole, sans<br />
aucun conflit d’intérêt ou liens d'intérêts ou contrainte<br />
promotionnelle avec qui qu’il soit ou quelqu’organisme ou<br />
institution / organisation que ce soit, étatique, paraétatique<br />
ou privé, industriel ou commercial en relation avec le sujet<br />
présenté.<br />
+243 - 851278216 - 899508675 - 991239212 - 902263541 - 813572818<br />
diasfb@mail2world.com<br />
Le <strong>Prototype</strong> 21 / 21 mercredi, 7. novembre 2018