Page 1

IT ÉRATIONS, G ÉN ÉRATEUR, YIELD et NEXT E S 10 I t é r a t e u r s , G é n é r a t e u r s , & Itérables J AVA S C R I P T (Programmation Internet) V O L . V I J.B. Dadet DIASOLUKA Luyalu Nzoyifuanga +243 - 851278216 - 899508675 - 991239212 - 902263541 - 813572818

CHAPITRE 10 : G ÉN ÉRATEUR, YIELD et NEXT : Les générateurs sont des fonctions qu'on peut quitter puis reprendre (continuer). Le contexte d'un générateur (les liaisons avec ses variables) est sauvegardé entre deux invocations. C’est donc aussi un bon moyen d’utiliser des variables statiques dans JavaScript, en plus des closures (fermetures, et curries [currying ou Curryfication]). Le corps d’une fonction génératrice function* (« generator », notez l’astérisque) n'est pas exécuté immédiatement lors de la création/définition d’une variable, mais plutôt renvoie un objet ayant seulement deux propriétés, la première ayant le nom « value » et qui emmagasine la valeur retournée par yield, la deuxième ayant le nom « done » qui indique si le générateur est toujours actif (pas terminé). La 1ère fois que la méthode « .next() » est appelé de l’objet itérateur créé, le corps de la fonction génératrice est exécuté de son début jusqu'à la première occurrence de l’instruction yield rencontrée, qui définira la valeur à


renvoyer à l’objet itérateur qui l’aura appelé avec cette instruction « .next ». N.B. : Un « objet itérateur » est créé sans l’opérateur « new ». Tout comme la commande return, la commande yield renvoie une valeur de retour mais dans la propriété .value de l’objet itérateur. La commande return quant à elle renvoie la valeur de retour dans le propre type de cette dernière. Contrairement à return, yield ne clôt pas l’exécution de la fonction génératrice mais la suspend seulement pour être poursuivie à l’invocation de la prochaine méthode .next(), qui exécutera jusqu’à la rencontre de la prochaine instruction yield ou return. <script> function* repSces(obj) { console.log("Avant yield"); yield obj; } let it = repSces( console.log("Génération en cours")); console.log("Appel à .next()"); console.log(`it.next()= `, it.next()); </script>


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI

En simple, on peut dire que 1. yield est une sorte de return qui contrairement à ce dernier ne clôt pas mais suspend/interrompt l’exécution de la fonction génératrice. La valeur de la propriété « générateur.done » demeure true. 2. return retourne aussi une valeur mais clôt le générateur, la valeur de la propriété « générateur.done » devenant false. 3. Cette fonction génératrice est définie avec le mot clé iterator. 4. La méthode .next(), appelée pour la première fois, exécute toute la fonction génératrice jusqu’à yield. Itérateur–Générateur–Itérables -4/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI

Les prochaines fois que .next() est appelée, elle poursuit l’exécution de la fonction génératrice là où yield l’avait suspendue. 5. Chaque appel à la méthode .next() doit avoir un yield qui lui est associé dans le générateur. Une façon facile de le garantir est d’utiliser une boucle valide qui contient l’instruction yield. Pendant qu’on est dans cette boucle yield renvoie une valeur valide, dès qu’on quitte la boucle elle (yield) renvoie undefined, à moins de prévoir des yield supplémentaire après et en dehors de cette boucle. 6. Mais il n’est pas nécessaire (bien que souvent inutile) d’avoir plus de yield dans le générateur que de .next() appelées.

Itérateur–Générateur–Itérables -5/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI

7. Un yield n’est pas obligé d’être dans une boucle. 8. Tout comme return, yield renvoie des valeurs de tout type, pas seulement des booléennes, mais il (le yield) n’est pas non plus obligé d’en renvoyer explicitement, par exemple quand le .next() qui l’appelle utilise un ou des arguments. 9. La valeur de retour de yield peut être utilisée « in situ » [ex. console.log(yield)] ou être recueillie à partir de la propriété .« value » de la méthode .next() de l’obet générateur [ex. gen.next().value]. 10. Comme yield ne clôt pas la fonction mais seulement la suspend, les variables locales de la fonction génératrice persistent donc après cette suspension par yield. En fait on peut comprendre la méthode « next » comme demandant au « yield » d’envoyer la prochaine valeur de retour. 11. La boucle « for…of » agit sur les « itérables », tandis que la boucle « for…in » agit sur les « énumérables ». Mais « yield » « itérable » :

permet

aussi

de

créer

un

objet

<script type="text/javascript"> "use strict"; const iterable = { *[Symbol.iterator]() { yield "Date() = " + Date(); yield "Date.now() = " + Date.now();

Itérateur–Générateur–Itérables -6/57mars 2019 (11:25 )

dimanche, 17.


}

J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI yield "Math.PI = " + Math.PI; yield "Math.E = " + Math.E;

} for (let i of iterable) { console.log(i); } </script>

<script> function* repSces(obj) { const couples = Object.getOwnPropertyNames(obj); // ou // const couples = Reflect.ownKeys(obj);

}

for (const cle of couples) { yield [cle, obj[cle]]; }

// Les couples [cle,val] ds chaque objet-membre // de l'Array diags const diags = [ { nom: 'Likelele', sce: "Ophtalmo", path: "Cataracte" }, { nom: 'Monzele', sce: "Gynéco", path: "Leucorrhée" }, { nom: 'Ntaba', sce: "Vétérinaire", path: "Rage" } ]; let c=0; while(c < diags.length){ // Retourner un itérable pour chaque membre de diags.

Itérateur–Générateur–Itérables -7/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI for (const [id,svce] of repSces(diags[c++])) { // Retourner [cle,val] pour chaque couple d'un // membre de diags. console.log(`${id}: ${svce}`); } console.log(`${"=".repeat(20)}`);

} </script>

Une extension de ce qui précède : I. Tous les traitements faits dans « *[Symbol.iterator]() {}

» <script type="text/javascript"> "use strict"; let flagt=0, flagc=0, c=0, m = ["carie","parodontite","tartre","gingivite"]; const it = { *[Symbol.iterator]() { for(let k of m) {

Itérateur–Générateur–Itérables -8/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI if(k=="tartre") flagt++; if(k=="crouzon") flagc++; yield ++c+". "+k; }

}

} for (let i of it) console.log(i); if(flagt)console.log("tartre était là"); if(flagc)console.log("Crouzon était là"); else console.log("Crouzon n'était pas là"); </script>

II. Tous les traitements faits en dehors « *[Symbol.iterator]() {}

», avec quelques modifications aussi : <script type="text/javascript"> "use strict"; let flagt=0, flagc=0, c=-2, m = ["carie","tartre","parodontite","gingivite"]; const it = { *[Symbol.iterator]() { for (let k of m) yield c+=2; } } for (let i of it){ if(m[i]=="tartre") flagt++; if(m[i]=="crouzon") flagc++; console.log(m[i]);

Itérateur–Générateur–Itérables -9/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI } if(flagt)console.log("tartre était retenue"); else console.log("tartre n'était pas retenue"); if(flagc)console.log("Crouzon était là"); else console.log("Crouzon n'était pas là"); </script>

Un exemple pratique de la boucle itératrice « for… of » : Toutes les combinaisons 3 à trois des éléments de 3 Arrays de n’importe quelle taille : <script type="text/javascript"> "use strict"; const a1 = [3, 1, 6, 7], a2 = [8, 5, 0], a3 = [2, 4, 9, 5, 1]; let combo = [], t=""; for (let x of a1) for (let y of a2) for (let z of a3) combo.push([x , y , z]); let cptr=0; for (let v of combo) t += (++cptr).toString().padStart(2,'.') + ") " + v+' | '; console.log(t); </script>

Itérateur–Générateur–Itérables -10/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI

Voici en clair comment s’est fait et comment doit se faire facilement l’indexation même manuellement : <script type="text/javascript"> "use strict"; const a1 = [0, 1, 2, 3], a2 = [0, 1, 2, 3], a3 = [0, 1, 2, 3]; let combo = [], t=""; for (let x of a1) for (let y of a2) for (let z of a3) combo.push([x , y , z]); let cptr=0; for (let v of combo) t += (++cptr).toString() .padStart(2,String .fromCharCode(183)) + ") " + v+' | '; console.log(t); </script>

Itérateur–Générateur–Itérables -11/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI

Et avec des lettres : <script type="text/javascript"> "use strict"; const a1 = ["L", "U", "Y"], a2 = ["L", "U", "Y"], a3 = ["L", "U", "Y"]; let combo = [], t=""; for (let x of a1) for (let y of a2) for (let z of a3) combo.push([x , y , z]); let cptr=0; for (let v of combo) t += (++cptr).toString() .padStart(2,String .fromCharCode(183)) + ") " + v+' | '; console.log(t); </script>

Itérateur–Générateur–Itérables -12/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI

Syntaxe de base d’une fonction génératrice : Déclaration de la fonction-génératrice : function* genFct(){ // Notez l’astérisque * var idx = 0; while (idx <= lim) // test de la condition yield idx++; // operation et ret value }

Appel de la fonction itératrice : L’appel à une fonction génératrice ne l’exécute pas (n’exécute pas son corps), mais crée un objet « itérateur » qui permettra de contrôler ce corps de la fonction. Notez ici qu’on crée l’objet itérateur sans l’opérateur « new ». let it = genFct(); // Défnition de l’itérateur // = création de l'objet itérateur « it ». it.next(); it.next(); it.next(); it.next();

// // // //

Appel Appel Appel Appel

du du du du

premier yield via « it » prochain yield " prochain yield " prochain yield "

Itérateur–Générateur–Itérables -13/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI

Exemple : <script type="text/javascript"> "use strict"; let cl = console.log; // Définition d'un générateur avec * function* fGenerator() { let current = 9; while (true) { // Boucle Indispensable yield current++; } yield; } // Fin Définition du générateur const it = fGenerator(); // Déf itérateur par appel au générateur cl(it.next().value); // 9 cl(it.next().value); // 10 cl(it.next().value.toString(2), " base 2"); // 1011 cl(it.next().value.toString(4), " base 4"); // 30 cl(it.next().value.toString(8), " base 8"); // 15 cl(it.next().value.toString(10), " base 10"); // 14 cl(it.next().value.toString(15), " base 15"); // 10 cl(it.next().value.toString(16), " base 16"); // 10 </script>

Pour le cas ci-dessus, à la place de « while ( true ) » on peut utiliser « for ( ; ; ) » ou « do {...} while ( true ) », et à la place de true on peut utiliser n’importe quel test conditionnel valide : <script type="text/javascript"> "use strict"; function* numeroter(){ // Constructeur var index = 0; do{ yield index++;

Itérateur–Générateur–Itérables -14/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI // prochaine instruction = do{}, tant que // la condition de la boucle est remplie. } while(index < 3) console.log("1er next Après la boucle") // Ne sera exécuté qu'une seule fois quand // la condition de la boucle n’est plus remplie, // avant le yield (return du generator) du // premier next quand on quitte la boucle. } // Fin function* numeroter() var it = numeroter(); console.log(it.next().value); console.log(it.next().value); console.log(it.next().value); console.log(it.next().value); console.log(it.next().value); console.log(it.next().value); </script>

// // // // // //

0 1 2 1er next Après la boucle undefined undefined

Une autre version de ça : <script type="text/javascript"> "use strict"; function* numeroter(){ // Constructeur var index = 0; do{ yield index++; } while(index < 12); console.log("1er next Après la boucle") } // Fin function* numeroter() const nc = [ "I = OLFACTIF, Se", "II = OPTIQUE, SDe", "III = OCULO-MOTEUR COMMUN (innerve tous les "+ "autres muscles extrinsèques, la musculature "+ "intrinsèque [muscle ciliaire {accommodation} "+ "et sphincter de l'iris], et le releveur de "+ "paupière supérieure), Mo", "IV = PATHÉTIQUE (=trochléaire. Innerve le "+ "grand oblique), Mo", "V = TRIJUMEAU, Mi",

Itérateur–Générateur–Itérables -15/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI "VI = OCULO-MOTEUR EXTERNE (=abducens. "+ "Innerve le droit externe), Mo", "VII = FACIAL (Mi)", "VIII = VESTIBULO-COCHLÉAIRE, Se", "IX = GLOSSO-PHARYNGIEN, Mi", "X = PNEUMOGASTRIQUE (=Vague), Mi", "XI = SPINAL (=accessoire), Mi", "XII = GRAND HYPOGLOSSE, Mi."

]; var it = numeroter();

do{ var c = it.next().value; console.log(`* ${c+1}è paire => ${nc[c]}`); } while(nc[c]!=="XII = GRAND HYPOGLOSSE, Mi."); </script>

Et avec la boucle « for ... in » : Itérateur–Générateur–Itérables -16/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI <script type="text/javascript"> "use strict"; function* numeroter(){ // Constructeur var idx = [0,10,20,30]; for (let k in idx) {// prochaine instruction = for{ yield idx[k]; } // 0 10 20 30 undefined } var it = numeroter(); console.log(it.next().value); console.log(it.next().value); console.log(it.next().value); console.log(it.next().value); console.log(it.next().value); </script>

// // // // //

0 10 20 30 undefined

Quand on quitte la boucle de la fonction génératrice, celle-ci ne se clôt pas, mais le yield renvoie alors undefined. <script type="text/javascript"> "use strict"; function* numeroter(){ // Constructeur var idx = [0,20,10,30]; for (let k in idx) { yield idx[k]>15; } // false true false true undefined } var it = numeroter(); console.log(it.next().value); console.log(it.next().value); console.log(it.next().value); console.log(it.next().value); console.log(it.next().value); </script>

// // // // //

false true false true undefined

. next() exécute toujours, et Itérateur–Générateur–Itérables -17/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI

yield retourne une valeur de n’importe quel type. <script type="text/javascript"> "use strict"; function* numeroter(){ // Constructeur var diag = { Conjonctivite:"sécrétions", Myopie:"lunettes", Rétinoblastome:"masse", Perforation:"herniation" }, // Object literal ([définition] littéral d’objet). ard=[ "Conjonctivite", "Myopie", "Rétinoblastome", "Perforation" ]; for (let idx=0;;idx++) { yield diag[ard[idx]]; } // sécrétions lunettes defi-ned }

masse

herniation

un-

var it = numeroter(); console.log(it.next().value); console.log(it.next().value); console.log(it.next().value); console.log(it.next().value); console.log(it.next().value); console.log(it.next().value); </script>

// // // // // //

sécrétions lunettes masse herniation undefined undefined

Une autre façon d’écrire ce même code : <script type="text/javascript"> "use strict"; function* numeroter(){ // Constructeur var index = 0;

Itérateur–Générateur–Itérables -18/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI do{ yield index++; // prochaine instruction = do{}, tant que // la condition de la boucle est remplie. } while(index < 3) console.log("1er next Après la boucle") // 1er next Après la boucle // // Ne sera exécuté qu'une seule fois quand // la condition de la boucle n’est plus remplie, // avant le yield (return du generator) du // premier next quand on quitte la boucle. } // Fin function* numeroter() var it = numeroter(); const diag = { Conjonctivite:"sécrétions", Myopie:"lunettes", Rétinoblastome:"masse", Perforation:"herniation" }; let c; c = it.next().value; console.log(Object.entries(diag)[c][0], Object.entries(diag)[c][1]); // Conjonctivite sécrétions c = it.next().value; console.log(Object.entries(diag)[c][0], Object.entries(diag)[c][1]); // Myopie lunettes c = it.next().value; console.log(Object.entries(diag)[c][0], Object.entries(diag)[c][1]); // Rétinoblastome masse c = it.next().value; console.log(Object.entries(diag)[c][0],

Itérateur–Générateur–Itérables -19/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI Object.entries(diag)[c][1]); // TypeError: // Object.entries(...)[c] is undefined; // can't access element at index 0 </script>

La méthode .next() du générateur : La méthode .next() renvoie un objet dont : 1. La propriété value contient la valeur générée (par yield) et peut être manipulée librement. 2. Une propriété done qui indique si la boucle de la fonction génératrice est toujours active, donc si le générateur a ou pas produit sa dernière valeur soit-elle valide ou pas même quand la valeur retournée est undefined. AFFICHAGE DIRECT DE LA STRUCTURE INTERNE DE L’OBJET GÉNÉRATEUR : <script type="text/javascript"> "use strict"; function* Generator() { yield "Valeur retournée par yield"; } var gen = Generator(); var r; r=gen.next(); console.log(r); // Object { // value: "Valeur retournée par yield", // done: false // } //

Itérateur–Générateur–Itérables -20/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI // // {…} // done: false // value: "Valeur retournée par yield" // <prototype>: Object { … } </script>

AFFICHAGE VIA Object.getOwnPropertyDescriptors(yield retval) : <script type="text/javascript"> "use strict"; function* Generator() { yield "Valeur retournée par yield"; } var gen = Generator(); var r; r=gen.next(); console.log(Object.getOwnPropertyDescriptors(r)) // // // // // // // // // // // // // // // // //

DANS CONSOLE DE FIREFOX 62.0.2 : Object { value: {…}, done: {…} } 1er niveau de détails (Firefox) : {…} done: Object { value: false, writable: true, enumerable: true, … } value: Object { value: "Valeur retournée par yield", writable: true, enumerable: true, … }

Itérateur–Générateur–Itérables -21/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI <prototype>: Object { … }

// // // // 2e niveau de détails (Firefox) : // // done: {…} // configurable: true // enumerable: true // value: true // writable: true // <prototype>: Object { … } // value: {…} // configurable: true // enumerable: true // value: undefined // writable: true // <prototype>: Object { … } // <prototype>: Object { … } // // // // // // // // // // // // // // // // // // // // // // //

DANS CONSOLE DE YANDEX Version 18.10.1.385 beta {value: "Valeur retournée par yield", done: false} {value: {…}, done: {…}} 1er niveau de détails (Yandex) : done: { value: false, writable: true, enumerable: true, configurable: true } value: { value: "Valeur retournée par yield", writable: true, enumerable: true, configurable: true } __proto__: Object

Itérateur–Générateur–Itérables -22/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI // // 2e niveau de détails (Yandex) : // // done: // configurable: true // enumerable: true // value: false // writable: true // __proto__: Object // value: // configurable: true // enumerable: true // value: "Valeur retournée par yield" // writable: true // __proto__: Object // __proto__: Object </script>

AFFICHAGE retval) :

VIA

Object.getOwnPropertyNames(yield

<script type="text/javascript"> "use strict"; function* Generator() { yield "Valeur retournée par yield"; } var gen = Generator(); var r; r=gen.next(); console.log(Object.getOwnPropertyNames(r)) // // // // // // //

DANS CONSOLE DE FIREFOX 62.0.2 : Array [ "value", "done" ] Un seul (1er) niveau de détails (Firefox) : (2) […]

Itérateur–Générateur–Itérables -23/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI 0: "value" 1: "done" length: 2 <prototype>: Array []

// // // // // // // // // // // // // // // // //

DANS CONSOLE DE YANDEX Version 18.10.1.385 beta (2) ["value", "done"] Un seul (1er) niveau de détails (Yandex) : (2) ["value", "done"] 0: "value" 1: "done" length: 2 __proto__: Array(0)

</script>

Les propriétés « value » et « done » de l’objet retourné par yield sont utilisées comme celles de tout autre objet (obj.prop). <script type="text/javascript"> "use strict"; function* numeroter(){ // Constructeur var diag = { Conjonctivite:"sécrétions", Myopie:"lunettes", Rétinoblastome:"masse", Perforation:"herniation" }, // Object literal ([définition] littéral d’objet). ard=[ "Conjonctivite", "Myopie", "Rétinoblastome", "Perforation"

Itérateur–Générateur–Itérables -24/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI ]; for (let idx=0;;idx++) { yield diag[ard[idx]]; } // sécrétions lunettes ned }

masse

herniation

undefi-

var gen = numeroter(); let r; r=gen.next(); console.log(r.value r=gen.next(); console.log(r.value r=gen.next(); console.log(r.value r=gen.next(); console.log(r.value r=gen.next(); console.log(r.value r=gen.next(); console.log(r.value </script>

+ " " + r.done); // sécrétions false + " " + r.done); // lunettes false + " " + r.done); // masse false + " " + r.done); // herniation false + " " + r.done); // undefined false + " " + r.done); // undefined false

La valeur generator.done du générateur devient true dès qu’on a fini avec le générateur : 1er exemple : <script type="text/javascript"> "use strict"; var r; function* idMaker() { var index = 2; while (Math.abs(index) < Math.abs(index+1)) yield index--; } var gen = idMaker();

Itérateur–Générateur–Itérables -25/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI console.log(r.value , r.done); console.log(r.value , r.done); console.log(r.value , r.done); console.log(r.value , r.done);

r=gen.next(); // r=gen.next(); // r=gen.next(); // r=gen.next(); // true r=gen.next(); console.log(r.value , r.done); // true r=gen.next(); console.log(r.value , r.done); // true </script>

2 false 1 false 0 false undefined undefined undefined

2e exemple : <script type="text/javascript"> "use strict"; function* numeroter(){ // Constructeur var index = 0; do{ yield index++; // prochaine instruction = do{}, tant que // la condition de la boucle est remplie. } while(index < 3) console.log("1er next Après la boucle") // Ne sera exécuté qu'une seule fois quand // la condition de la boucle n’est plus remplie, // avant le yield (return du generator) du // premier next quand on quitte la boucle. } // Fin function* numeroter() var gen = numeroter(); let r; r=gen.next(); console.log(r.value+" "+r.done); // 0 false r=gen.next(); console.log(r.value+" "+r.done); // 1 false r=gen.next(); console.log(r.value+" "+r.done); // 2 false r=gen.next(); console.log(r.value+" "+r.done); // 1er next Après la boucle // undefined

Itérateur–Générateur–Itérables -26/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI r=gen.next(); console.log(r.value+" "+r.done); // undefined true r=gen.next(); console.log(r.value+" "+r.done); // undefined true // 0 false // 1 false // 2 false // 1er next Après la boucle // undefined true // undefined true // undefined true </script>

test.html:21:1 test.html:23:1 test.html:25:1 test.html:10:3 test.html:27:1 test.html:29:1 test.html:31:1

Ci-dessous aussi, on quitte la boucle quand idx atteint ou dépasse 3 [ for (let idx=0;idx<3;idx++) ]. En ce momentlà aussi, generator.done est devenu true. <script type="text/javascript"> "use strict"; function* numeroter(){ // Constructeur var diag = { Conjonctivite:"sécrétions", Myopie:"lunettes", Rétinoblastome:"masse", Perforation:"herniation" }, // Object literal ([définition] littéral d’objet). ard=[ "Conjonctivite", "Myopie", "Rétinoblastome", "Perforation" ]; for (let idx=0;idx<3;idx++) { yield diag[ard[idx]]; } // sécrétions false, lunettes false, // undefined true, undefined true,

masse false undefined true

}

Itérateur–Générateur–Itérables -27/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI var gen = numeroter(); let r; r=gen.next(); console.log(r.value r=gen.next(); console.log(r.value r=gen.next(); console.log(r.value r=gen.next(); console.log(r.value r=gen.next(); console.log(r.value r=gen.next(); console.log(r.value // sécrétions false // lunettes false // masse false // undefined true // undefined true // undefined true </script>

+ " " + r.done); // sécrétions false + " " + r.done); // lunettes false + " " + r.done); // masse false + " " + r.done); // undefined true + " " + r.done); // undefined true + " " + r.done); // undefined true test.html:28:1 test.html:30:1 test.html:32:1 test.html:34:1 test.html:36:1 test.html:38:1

Passation d’arguments à la fonction génératrice : On peut passer des arguments à la fonction génératrice lors de sa définition. Ces arguments se comportent dans la fonction génératrice exactement comme les paramètres des fonctions ordinaires. [En passant signalons que comme d’habitude, il est recommandé de ne jamais modifier la valeur de ces paramètres (mais on peut le faire si on veut) ; au besoin on ferait mieux d’affecter leurs valeurs à des variables locales]. <script type="text/javascript"> "use strict"; var v; function* generator(g,p) {// Constructeur console.log("Exécution du 1er yield")

Itérateur–Générateur–Itérables -28/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI yield ; // retourne undefined console.log("Exécution du 2e yield") yield g; console.log("Exécution du 3e yield") yield g + v; console.log("Exécution du 4e yield") yield p + v; console.log("Exécution du 5e yield") yield g * p + v; } var gen = generator(5,10); console.log("Après définition du générateur"); v = 7; // Et/ou autres instructions... console.log(gen.next().value); // undefined v = 15; console.log(gen.next().value); // 5 v = 25; console.log(gen.next().value); // 30 v = 30; console.log(gen.next().value); // 40 v = 40; console.log(gen.next().value); // 90 console.log(gen.next().done)

// true

// RÉSULTATS // Après définition du générateur test.html:21:3 // Exécution du 1er yield test.html:4:6 // undefined test.html:24:3

Itérateur–Générateur–Itérables -29/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI // Exécution du 2e yield test.html:7:6 // 5 test.html:27:3 // Exécution du 3e yield test.html:10:6 // 30 test.html:30:3 // Exécution du 4e yield test.html:13:6 // 40 test.html:33:3 // Exécution du 5e yield test.html:16:6 // 90 test.html:36:3 // true test.html:38:3 </script>

L’appel de la méthode .next() avec un argument reprendra l'exécution de la fonction génératrice, comme d’habitude là où elle s’était interrompue, et cet argument deviendra la valeur de retour de yield (remplacera la valeur de l'expression yield sans rien d’autre) mais à utiliser in situ (inline) : cet argument de .next() passé au générateur n’est pas retournée dans la propriété value de l’objet générateur. Vérifiez ci-dessous l’ordre d’exécution dans l’affichage de la console, et notez que l’argument du premier « appel au générateur avec argument » (« 1. Keliol ») n’a pas été utilisé (n’est pas affiché). <script type="text/javascript"> "use strict"; function* Generator() { console.log("0è instructions suite..."); yield "Depuis le générateur"; console.log("*** 1ère Série d'instructions..."); console.log(yield); console.log("*** 2ès instructions"); yield;

Itérateur–Générateur–Itérables -30/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI console.log("*** 3ès instructions"); console.log(yield); console.log("*** 4ès instructions"); console.log(yield); console.log("*** 5ès instructions"); console.log(yield);

}

console.log("*** 6ès instructions"); console.log(yield); var gen = Generator();

// yield récupère automatiquement les arguments. console.log(gen.next().value); console.log(gen.next()('1. Keliol').value); console.log(gen.next()('2. Baron').value); console.log(gen.next()('3. Petrosa').value); console.log(gen.next()('4. Kelantina').value); </script>

Exécution : 0è instructions suite... Depuis le généérateur *** 1ère Série d'instructions... undefined 2. Baron *** 2ès instructions undefined *** 3ès instructions undefined 4. Kelantina *** 4ès instructions undefined

test.html:3:3 test.html:28:4 test.html:6:3 test.html:29:4 test.html:7:3 test.html:9:3 test.html:30:4 test.html:12:3 test.html:31:4 test.html:13:3 test.html:15:3 test.html:32:4

Itérateur–Générateur–Itérables -31/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI

L’instruction return dans un générateur termine le générateur (done devenant true). La valeur renvoyée par return sera la valeur de terminaison du générateur. Une fois un générateur terminé, il ne peut plus produire d'autres valeurs. <script type="text/javascript"> "use strict"; var r; function* Generator() { console.log("*** 1ère Série d'instructions"); console.log("^^^^^^^",yield "Initio"); // Exécute d'abord yield (donc rentre vers le next appelant), // et donc interrompt et quitte le générateur sans le fermer, // et donc le console.log() ci-dessus // sera exécuté seulement au prochain .next(), mais // pas avec la valeur en cours de yield ("Initio"), mais // ave l'argument éventuel du .next() suivant ("2. Keliol..."). // Voir l'ordre d'exécution dans l'affichage de la console. console.log("*** 2ès instructions"); console.log("^^^^^^^",yield); console.log("*** 3ès instructions"); return 45; // unreachable code after return statement

test.html:10:5

console.log("*** 4ès instructions"); console.log(yield); console.log("*** 5ès instructions"); console.log(yield); console.log("*** 6ès instructions"); console.log(yield);

Itérateur–Générateur–Itérables -32/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI } var gen = Generator(); r=gen.next(); console.log("=>",r,r.value,r.done," <="); // yield récupère automatiquement les arguments de .next(). r=gen.next()('2. Keliol [2è next]'); console.log(r,r.value,r.done); r=gen.next()('3. Baron [3è next]'); console.log(r,r.value,r.done); r=gen.next()('4. Petrosa [4è next]'); console.log(r,r.value,r.done); // value = 45 , done = true r=gen.next()('5. Kelantina [5è next]'); console.log(r,r.value,r.done); console.log("Les autres instructions exécutent..."); // *** 1ère Série d'instructions // test.html:4:6 // => Object { value: "Initio", done: false } Initio false <= // test.html:38:4 // ^^^^^^^ 2. Keliol [2è next] // test.html:6:6 // *** 2ès instructions // test.html:16:6 // Object { value: undefined, done: false } undefined false // test.html:43:6 // ^^^^^^^ 3. Baron [3è next] // test.html:17:6 // *** 3ès instructions

Itérateur–Générateur–Itérables -33/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI // test.html:19:6 // Object { value: 45, done: true } 45 true // test.html:46:10 // Object { value: undefined, done: true } undefined true // test.html:49:6 // Object { value: undefined, done: true } undefined true // test.html:53:6 // Les autres instructions exécutent... // test.html:55:4 // unreachable code after return statement [En savoir plus] // test.html:24:5 </script>

Tentative de l’explication de l’Ordre d’exécution du code ci-dessus : 1. var gen = Generator(); Définition du générateur. 2. r=gen.next(); Demande d’exécuter le générateur jusqu’au premier yield y rencontré, ce qui poussera yield à renvoyer une valeur de retour à ce .next(), puis suspendre immédiatement l’exécution du générateur (pour notre cas ici même l’exécution du reste du console.log) et continuer l’exécution exactement à l’endroit où .next() l’a envoyée vers le générateur. L’exécution du programme s’y poursuivra jusqu’à rencontrer éventuellement le prochain .next() qui la redirigera de nouveau vers le générateur, exactement là où elle s’y est interrompue. Pour notre cas présent le programme reprendra l’exécution de « console.log ( " ^^^^^^^ " , yield " Initio " ) ; »,

c’est-à-dire d’abord la chaîne " ^^^^^^^ " puis la valeur Itérateur–Générateur–Itérables -34/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI

proposée à yield, mais ce paramètre n’est plus le même et vaut maintenant la valeur de l’argument du .next() en cours (le deuxième .next()) et qui est : « '2 . Keliol [2è next ] ' »

3. Jusque-là le programme aura donc exécuté et affiché : console.log ( " *** 1ère Série d'instructions " ) ; => *** 1ère Série d'instructions

et retourné un « value="Initio" »

test.html:4:6

objet à

générateur avec l’instruction

console.log ( " => " , r , r . value , r . done , " <= " ) ;

qui

se

trouve

dans

l’appelant

et

=> Object { value: " Initio " , done: false } Initio false <=

aura

affiché : test.html:38:4

4. Le programme poursuivra son exécution normale dans l’appelant, jusqu’au prochain .next() (le deuxième) dans l'instruction ci-dessous : r = gen . next ( ' 2. Keliol [ 2è next ] ' ) ;

À ce niveau-là le programme interrompra encore sa file dans l’appelant pour se rendre dans le générateur là où elle l’a quittée, pour y continuer son exécution, c’est-à-dira la suite de l’affichage de l’instruction « console . log ( yield ) ; » ,

avec les nouveaux paramètres de yield : « ‘2 . Keliol [ 2è next ] ' ». Le programme y poursuivra l’exécution de la console qu’elle avait abandonnée, mais avec les Itérateur–Générateur–Itérables -35/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI

paramètres

en

cours,

^^^^^^^ 2. Keliol [2è next] 5.

ce

qui

affichera

test.html:6:6.

Le programme poursuit par la suite son exécution dans le générateur jusqu’au prochain yield ou return. Il croise dans l’entretemps l’instruction console . log ( " *** 2ès instructions " ) ;

qu’il

exécute

*** 2ès instructions

en

affichant :

test.html:16:6

Cette instruction étant une ordinaire, le programme se poursuit jusqu’au console.log(yield);

Pendant l’exécution de cette dernière instruction (console.log(yield)), le programme exécutera naturellement d’abord l’argument de l’instruction c’est-à-dire le yield, qui retournera au générateur à l’objet générateur le paramètre du .next() qui a appelé son générateur, et qui devrait être affichée avec l’instruction ci-dessous : Console . log ( r , r . value , r . done ) ;

pour

afficher :

Object { value : undefined , done : false } undefined false test.html:43:6

6. Le programme poursuit son exécution dans l’appelant jusqu’au prochain .next() (le troisième) : Itérateur–Générateur–Itérables -36/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI r = gen . next ( ' 3 . Baron [ 3è next ] ' ) ;

Le programme exactement là l’instruction

rentre où il

donc dans l’a quitté,

le générateur c’est-à-dire à

console . log ( " ^^^^^^^ " , yield ) ;

Là, il continue l’affichage qu’il avait interrompu, comme expliqué plus haut, avec une nouvelle données pour yield (l’argument du .next() en cours), qui est : ' 3. Baron [ 3è next ] '

pour afficher : ^^^^^^^ 3. Baron [3è next] test.html:17:10

Il y continue jusqu’à rencontrer le prochain yield, c’est-à-dire exécute d’abord console . log ( " *** 3ès instructions " ) ; en affichant *** 3ès instructions test.html:19:6

puis continue jusqu’à rencontrer return qui clôt le générateur, tout en renvoyant la valeur arbitraire 45, comme ceci : return 45;

Itérateur–Générateur–Itérables -37/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI

7. Le programme rentre donc dans l’appelant en renvoyant la valeur 45 à l’objet générateur dans l’appelant, pour y exécuter l’instruction console . log ( r , r . value , r . done ) ;

qui affiche : Object { value: 45, done: true } 45 true test.html:46:6

indiquant aussi, avec la valeur,, que le générateur qui jusque-là était actif, est maintenant clos : gen . done == true .

Yield avec astérisque (yield*) : Avec yield* (yield avec astérisque) la génération des valeurs est déléguée à une autre fonction génératrice. <script type="text/javascript"> "use var r; function* autreGen(i) { yield i * 2; // pour *B*, retourne yield i * 3; // pour *C*, retourne yield i * 4; // pour *D*, retourne }

strict"; 30 = 15*2 45 = 15*3 60 = 15*4

var agen = autreGen(5); function* gen(i){ yield i; // Retourne 15 pour *A* seulement yield* autreGen(i); // délègue à yield* pour *B*, *C* et *D* // (puisque 3 yield ds autreGen), // avec i=15 (argument de yield*)

Itérateur–Générateur–Itérables -38/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI console.log("agen*** ",agen.next().value); // agen***

10

// 1er appel direct, donc 1er yiedl autreGen 10 = 5*2 yield i * 6; // Suite des yield dans gen, donc retourne 15*6 pour *E*

}

yield i * 7; // Retourne 15*7=105 pour *F*

var gen = gen(15); // i ds gen = 15 r=gen.next(); console.log("A**gen ",r.value,r.done); // A**gen false

15

r=gen.next(); console.log("B**gen ",r.value,r.done); // B**gen false

30

r=gen.next(); console.log("C**gen ",r.value,r.done); // C**gen false

45

r=gen.next(); console.log("D**gen ",r.value,r.done); // D**gen false

60

r=gen.next(); console.log("E**gen ",r.value,r.done); // E**gen false

90

r=gen.next(); console.log("F**gen ",r.value,r.done); // F**gen false

105

r=gen.next(); console.log("F**gen ",r.value,r.done); // F**gen undefined true

Itérateur–Générateur–Itérables -39/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI // undefined : il n'y a plus de yield dans gen. </script>

On ne peut pas utiliser l’opérateur « new » avec les générateurs. On dit qu’ils ne sont pas constructibles. <script type="text/javascript"> "use strict"; function* f() {} var obj = new f; // TypeError: f n'est pas un constructeur </script>

Application : Génération aléatoire d’IMC en fonction de poids et tailles générés aléatoirement : <script type="text/javascript"> "use strict"; function* Generator() { let n=0; while(true){ var ech={ p : Math.round(Math.random()*60+20), t : Math.round(Math.random()*120+80) }, imc = ech["p"] * ech["p"] / ech["t"]; yield String(++n).padStart(2,'.')+ ". pds=" + String(ech["p"]).padStart(3,' ') +

" kg , taille=" + String(ech["t"]).padStart(4,' ')+ " cm , imc=" + imc.toPrecision(4) + " kg²/cm" ; } } var gen = Generator();

Itérateur–Générateur–Itérables -40/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI for(let k=0 ; k<20 ; k++){ var r = gen.next(); console.log(r.value); } </script>

Exéccution : .1. .2. .3. .4. .5. .6. .7. .8. .9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.

pds= pds= pds= pds= pds= pds= pds= pds= pds= pds= pds= pds= pds= pds= pds= pds= pds= pds= pds= pds=

79 53 26 26 34 26 63 64 22 74 41 28 34 46 58 36 77 43 51 29

kg kg kg kg kg kg kg kg kg kg kg kg kg kg kg kg kg kg kg kg

, , , , , , , , , , , , , , , , , , , ,

taille= taille= taille= taille= taille= taille= taille= taille= taille= taille= taille= taille= taille= taille= taille= taille= taille= taille= taille= taille=

198 127 89 95 184 180 153 109 124 88 182 119 171 176 192 190 163 177 149 181

cm cm cm cm cm cm cm cm cm cm cm cm cm cm cm cm cm cm cm cm

, , , , , , , , , , , , , , , , , , , ,

imc=31.52 imc=22.12 imc=7.596 imc=7.116 imc=6.283 imc=3.756 imc=25.94 imc=37.58 imc=3.903 imc=62.23 imc=9.236 imc=6.588 imc=6.760 imc=12.02 imc=17.52 imc=6.821 imc=36.37 imc=10.45 imc=17.46 imc=4.646

kg²/cm kg²/cm kg²/cm kg²/cm kg²/cm kg²/cm kg²/cm kg²/cm kg²/cm kg²/cm kg²/cm kg²/cm kg²/cm kg²/cm kg²/cm kg²/cm kg²/cm kg²/cm kg²/cm kg²/cm

test.html:23:7 test.html:23:7 test.html:23:7 test.html:23:7 test.html:23:7 test.html:23:7 test.html:23:7 test.html:23:7 test.html:23:7 test.html:23:7 test.html:23:7 test.html:23:7 test.html:23:7 test.html:23:7 test.html:23:7 test.html:23:7 test.html:23:7 test.html:23:7 test.html:23:7 test.html:23:7

Array de valeurs générées : <script type="text/javascript"> "use strict"; const obj = { *[Symbol.iterator]() { const max = 10; for (let i = 1; i <= max; i++) { yield i+". "+ Math.pow(2,i); } } };

Itérateur–Générateur–Itérables -41/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI for (let member of obj) { console.log(member); } </script>

Exécution : 1. 2 2. 4 3. 8 4. 16 5. 32 6. 64 7. 128 8. 256 9. 512 10. 1024

test.html:12:3 test.html:12:3 test.html:12:3 test.html:12:3 test.html:12:3 test.html:12:3 test.html:12:3 test.html:12:3 test.html:12:3 test.html:12:3

En matière de table d’exposents de 2, voici comment on peut encore mieux le faire avec le CURRYING : https://gist.github.com/kavitshah8/d8ba19d09334d8e08a 1f209fdbacb597/raw/d96f9bab8f5fbbf5b4d9227f48c73a6 848525524/curry2.js <script type="text/javascript"> "use strict"; function pow2x (a) { return Math.pow(2,a); } function compound (f) { return function (b) { return f(f(b)) } } for(let k=0;k<=10;k++){ console.log(2,"^",k,"=", pow2x(k) ) } console.log("")

Itérateur–Générateur–Itérables -42/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI var p=1; for(let k=0;k<=10;k++){ var res=compound(pow2x)(k) console.log(p,"^",2,"=", compound(pow2x)(k) ) p=res } // // // // // // // // // // //

2 2 2 2 2 2 2 2 2 2 2

^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^

0 1 2 3 4 5 6 7 8 9 10

= = = = = = = = = =

1 2 4 8 16 32 64 128 256 512 = 1024

test.html:12:23 test.html:12:23 test.html:12:23 test.html:12:23 test.html:12:23 test.html:12:23 test.html:12:23 test.html:12:23 test.html:12:23 test.html:12:23 test.html:12:23

// 1 ^ 2 = 2 test.html:18:3 // 2 ^ 2 = 4 test.html:18:3 // 4 ^ 2 = 16 test.html:18:3 // 16 ^ 2 = 256 test.html:18:3 // 256 ^ 2 = 65536 test.html:18:3 // 65536 ^ 2 = 4294967296 test.html:18:3 // 4294967296 ^ 2 = 18446744073709552000 // 18446744073709552000 ^ 2 = 3.402823669209385e+38 // 3.402823669209385e+38 ^ 2 = 1.157920892373162e+77 // 1.157920892373162e+77 ^ 2 = 1.3407807929942597e+154 // 1.3407807929942597e+154 ^ 2 = Infinity </script>

Et <script type="text/javascript"> "use strict"; function pow2x (a) { return Math.pow(2,a); } function compound (f) { return function (b) {

Itérateur–Générateur–Itérables -43/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI return function (c) { return Math.pow(f(f(b)),2) } }

}

for(let k=0;k<=10;k++){ console.log(2,"^",k," = ", pow2x(k) ) } console.log("") var p=1; for(let k=0;k<=10;k++){ var res=compound(pow2x)(k)(2) console.log(p,"^",2,"^",2,"=", compound(pow2x)(k)(2) ) p=Math.sqrt(res) } // // // // // // // // // // //

2 2 2 2 2 2 2 2 2 2 2

^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^

0 1 2 3 4 5 6 7 8 9 10

= = = = = = = = = =

1 2 4 8 16 32 64 128 256 512 = 1024

// // // // // // // // // //

1 ^ 2 ^ 2 = 4 2 ^ 2 ^ 2 = 16 4 ^ 2 ^ 2 = 256 16 ^ 2 ^ 2 = 65536 256 ^ 2 ^ 2 = 4294967296 65536 ^ 2 ^ 2 = 18446744073709552000 4294967296 ^ 2 ^ 2 = 3.402823669209385e+38 18446744073709552000 ^ 2 ^ 2 = 1.157920892373162e+77 3.402823669209385e+38 ^ 2 ^ 2 = 1.3407807929942597e+154 1.157920892373162e+77 ^ 2 ^ 2 = Infinity

Itérateur–Générateur–Itérables -44/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI // Infinity ^ 2 ^ 2 = Infinity </script>

Itérateur–Générateur–Itérables -45/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI

CHAPITRE 11 : IT ÉRATIONS D' ÉNUM ÉRABLES : Exemple d’itération : On peut créer un objet itérable en le définissant de type SET, dans une array, avec la commande var itObj = new Set() ;

On crée alors son intance avec la commande var itInst = iterable[Symbol.iterator]();

On parcourt les éléments de l’itérateur avec la méthode .next(), comme dans l’illustration ci-dessous : <script type="text/javascript"> "use strict"; const iterable = new Set([0,1,2,4,8,16,32,64,128,256,512,1024]); const it = iterable[Symbol.iterator](); let tot=""; while (true) { const res = it.next(); if (res.done) {

break;

}

const item = res.value; tot += item + " = 2^" + Math.log2(item) + " | "

} console.log(tot); </script>

Itérateur–Générateur–Itérables -46/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI

Exécution : 0

= 2^-Infinity 4 = 2^2 | 8 64 = 2^ 6 | 128 1024 = 2^10 | 2048 16384 = 2^14 | 32768

= = = =

| 1 = 2^0 | 2^ 3 | 16 = 2^ 7 | 256 = 2^11 | 4096 = 2^15 | 65536 =

2 = 2^ 1 | 2^ 4 | 32 = 2^ 5 | 2^ 8 | 512 = 2^ 9 | 2^12 | 8192 = 2^13 | 2^16 |

Exemple d’itération avec le caractère singulier ( ` ) = ASCII 96 ou 60H ou <ALT-7> <ESPACE> en keybFr. utilisé pour délimiter l'argument à la méthode. Ce programme d’illustration est trop long, il sera découpé et abondamment commenté dans les prochaines éditions. <script type="text/javascript"> "use strict"; var obj = { obj:{} , L:"A" , 1:"Un", deux:2 , array:["texte",9,{o:"objet",s:6}] }; // ACCÈS DIRECT AUX PROPRIÉTÉS console.log( obj['obj'] , obj[1] , obj['array'] , obj['array'][2] ) // Object { } Un Array [ "texte", 9, {…} ] // Object { o: "objet", s: 6 } // ITÉRATIONS D'ÉNUMÉRABLES // // `objet.${prop} <*> ${obj[prop]}` // console.log("---","***","---"); for (const prop in obj) { console.log(`objet.${prop} <*> ${obj[prop]}`); // Notez le caractère singulier ( ` ) // = ASCII 96 ou 60H ou <ALT-7><ESPACE> en keybFr. // utilisé pour délimiter l'argument à la méthode

Itérateur–Générateur–Itérables -47/57mars 2019 (11:25 )

dimanche, 17.


// // // //

} // // // // //

J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI console.log() « objet. » est un littéral arbitraire ${prop} donne le nom (clé) de la propriété, ${obj[prop]} donne la valeur de la propriété.

objet.1 <*> Un objet.obj <*> [object Object] objet.L <*> A objet.deux <*> 2 objet.array <*> texte,9,[object Object]

// FOR (var prop IN obj) // object // console.log("---","***","---"); for (var prop in obj) { console.log(prop+" -> "+obj[prop]); } // 1 -> Un // obj -> [object Object] // L -> A // deux -> 2 // array -> texte,9,[object Object] // Object.entries(obj). FOREACH (([CLE,VAL]) // object // console.log("---","***","---"); Object.entries(obj).forEach(([cle,val])=>console.log(cle+" <-> "+val)); // 1 <-> Un // obj <-> [object Object] // L <-> A // deux <-> 2 // array <-> texte,9,[object Object]

Itérateur–Générateur–Itérables -48/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI // Object.entries(obj) . FOREACH(([CLE]) // object // console.log("---","***","---"); Object.entries(obj).forEach(([cle]) => console.log(cle)); // 1 // obj // L // deux // array // Object.entries(obj) . FOREACH(([VAL]) // object // console.log("---","***","---"); Object.entries(obj).forEach(([,val]) => console.log(val)); // Un // Object { } // A // 2 // Array [ "texte", 9, {…} ] // FOR(var [cle,val] OF Object.entries(obj)) // object // console.log("---","***","---"); for(var [cle,val] of Object.entries(obj)) console.log("*"+cle+' ^ '+val); // *1 ^ Un // *obj ^ [object Object] // *L ^ A // *deux ^ 2 // *array ^ texte,9,[object Object] //

Object.VALUES(obj)

Itérateur–Générateur–Itérables -49/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI // object // console.log("---","***","---"); console.log(Object.values(obj)); // Array [ "Un", {}, "A", 2, […] ] // FOR (var idx IN obj.array) { // array // console.log("---","***","---"); for (var idx in obj.array) { console.log(idx+" <-> "+obj.array[idx]); } // 0 <-> texte // 1 <-> 9 // 2 <-> [object Object] // FOR (var idx=0 ; idx<L ; idx++) // array // console.log("---","***","---"); for (var idx=0,l=obj.array.length ; idx<l ; idx++) { console.log(idx+" <<-> "+obj.array[idx]); } // 0 <<-> texte // 1 <<-> 9 // 2 <<-> [object Object] // Object.ENTRIES(obj.array) . FOREACH(([idx]) // array // console.log("---","***","---"); Object.entries(obj.array).forEach(([idx]) => console.log(idx+" -> "+obj.array[idx])); // 0 -> texte // 1 -> 9 // 2 -> [object Object]

Itérateur–Générateur–Itérables -50/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI // FOR (var [idx] OF Object.entries(obj.array)) // array // console.log("---","***","---"); for(var [idx] of Object.entries(obj.array)) console.log("*"+idx+' ^ '+obj.array[idx]); // *0 ^ texte // *1 ^ 9 // *2 ^ [object Object] // Object.values(obj.array) // array // console.log("---","***","---"); console.log(Object.values(obj.array)); // Array [ "texte", 9, {…} ] // FOR (var p IN obj.array[2]) // array // console.log("---","***","---"); for (var p in obj.array[2]) { console.log(p+" -> "+obj.array[2][p]); } // o -> objet // s -> 6 // // Les indexes dans une Array sont juste des // propriétés énumerables avec comme noms // des entiers, et sont identiques aux // propriétés d'un objet en général. // FOR (var i IN s) // String // console.log("---","***","---"); let s="Diasol"; for (var i in s) { console.log(i+" -> "+s[i]);

Itérateur–Générateur–Itérables -51/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI } // // // // // //

0 1 2 3 4 5

-> -> -> -> -> ->

D i a s o l

// APPLICATIONS PRATIQUES // HASOWNPROPERTY(prop) // console.log("---","***","---"); let triangle = {a: 1, b: 2, c: 3}; let epaisseur = {ep:"epais"}; function ColoredTriangle() { this.color = 'red'; } ColoredTriangle.aimepar = 15; // prop non héritable ColoredTriangle.prototype = triangle; // héritable (prot) ColoredTriangle.prototype = epaisseur; // héritable (prot) ColoredTriangle.prototype.pds = 120; // héritable (prot) var obj = new ColoredTriangle(); obj.brillant = true; console.log("ColoredTriangle.aimepar = "+ColoredTriangle.aimepar); // ColoredTriangle.aimepar = 15 console.log("obj.aimepar = "+obj.aimepar); // obj.aimepar = undefined console.log("===> ownProperties de l'INSTANCE"); // ===> ownProperties de l'INSTANCE console.log("---","***","---"); console.log(Object.getOwnPropertyNames(obj)); // Array [ "color", "brillant" ]

Itérateur–Générateur–Itérables -52/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI for (const prop in obj) { console.log("> ",prop+ " <*> "+obj[prop]); // > color <*> red // > brillant <*> true // > ep <*> epais // > pds <*> 120 if (obj.hasOwnProperty(prop)) { console.log(`*** OWN PROP : obj.${prop} = $ {obj[prop]}`); } // *** OWN PROP : obj.color = red // *** OWN PROP : obj.brillant = true } console.log("---","***","---"); console.log("===> ownProperties du CONSTRUCTEUR"); // ===> ownProperties du CONSTRUCTEUR console.log(Object.getOwnPropertyNames(ColoredTriangle)); // Array [ "aimepar", "prototype", "length", "name" ] for (const prop in ColoredTriangle) { console.log("> ",prop+ " <*> "+ColoredTriangle[prop]); // > aimepar <*> 15 console.log("---","***","---"); if (ColoredTriangle.hasOwnProperty(prop)) { console.log(`*** OWN PROP : ColoredTriangle.${prop} = ${ColoredTriangle[prop]}`); } // *** OWN PROP : ColoredTriangle.aimepar = 15 } </script>

Exécution : 4 -> o test.html:191:6 5 -> l test.html:191:6 --- *** --- test.html:205:3

Itérateur–Générateur–Itérables -53/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI ColoredTriangle.aimepar = 15 test.html:221:1 obj.aimepar = undefined test.html:224:1 ===> ownProperties de l'INSTANCE test.html:227:1 --- *** --- test.html:230:3 Array [ "color", "brillant" ] test.html:231:3 > color <*> red test.html:235:3 *** OWN PROP : obj.color = red test.html:242:5 > brillant <*> true test.html:235:3 *** OWN PROP : obj.brillant = true test.html:242:5 > ep <*> epais test.html:235:3 > pds <*> 120 test.html:235:3 --- *** --- test.html:248:1 ===> ownProperties du CONSTRUCTEUR test.html:250:1 Array(4) [ "aimepar", "prototype", "length", "name" ] test.html:253:1 > aimepar <*> 15 test.html:257:3 --- *** --- test.html:260:3 *** OWN PROP : ColoredTriangle.aimepar = 15 test.html:262:5

Kinshasa, le Sunday 17 March 2019 - 12:00:07 a3/p3 Mots-clés : Variables statiques, Itération, énumérables, Set, function*, générateur, itérateur, fonction génératrice, iterator, yield, yield*, next, generator, constructibles, curry, currying, closures, fermetures, curries, curryfication, boucle, test conditionnel, javascript, opérateur new, ECMA, ECMASCRIPT, arguments, paramètres.

Itérateur–Générateur–Itérables -54/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI DIASOLUKA Nz. Luyalu

Docteur en Médecine, Chirurgie & Accouchements (1977), CNOM : 0866 - Spécialiste en ophtalmologie (1980)

Études humanités : Scientifique - Mathématiques & Physique.

Informaticien-amateur, Programmeur et WebMaster.

Chercheur indépendant, autonome et autofinancé, bénévole, sans aucun conflit d’intérêt ou liens d'intérêts ou contrainte promotionnelle avec qui qu’il soit ou quelqu’organisme ou institution / organisation que ce soit, étatique, paraétatique ou privé, industriel ou commercial en relation avec le sujet présenté. +243 - 851278216 - 899508675 - 991239212 - 902263541 - 813572818 diasfb@mail2world.com

Autre Lecture : https://www.scribd.com/document/374738470/Le-Plus-Grand-Secret-de-LaCreation

D’autres publications pouvant aussi intéresser : • https://www.scribd.com/document/377036251/LeDosage-Des-Medicaments-en-Cac-Cas • https://www.scribd.com/document/377035454/LeHasard-Des-Thermometres-Non-contact-a-Infrarouge • https://www.scribd.com/document/376222482/PetiteIntroduction-Aux-Fonctions-JavaScript Itérateur–Générateur–Itérables -55/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI

• https://www.scribd.com/document/376221919/La-Foien-Jesus-Christ-Pour-Quoi-Faire • https://www.scribd.com/document/375689778/Lacuitevisuelle-angulaire • https://www.scribd.com/document/375349851/Lavariable-This • https://www.scribd.com/document/375024162/FonctionsImbriquees-en-JS • https://www.scribd.com/document/374789297/FormatInterne-Des-Objets-JavaScript • https://www.scribd.com/document/374788758/Iterationsen-JavaScript • https://www.scribd.com/document/374738470/Le-PlusGrand-Secret-de-La-Creation • https://www.scribd.com/document/374597969/NouvelleFormule-d-IMC-indice-de-doduite-Selon-Dr-Diasoluka • https://www.scribd.com/document/373847209/PropertyDescriptors • https://www.scribd.com/document/373833282/l-ObjetGlobal-Window • https://www.scribd.com/document/372665249/JavascriptTome-II • https://www.scribd.com/document/355291488/motiliteoculaire-2 • https://www.scribd.com/document/355291239/motiliteItérateur–Générateur–Itérables -56/57mars 2019 (11:25 )

dimanche, 17.


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI

oculaire-I • https://www.scribd.com/document/355290248/Script-dAnalyses-Des-Reflexes-Pupillomoteurs • https://www.scribd.com/document/321168468/Renseigne ments-Id-et-Anthropometriques • https://www.scribd.com/document/320856721/Emission31-Jul-2016 • https://www.scribd.com/document/318182982/Complicati on-Visuelle-du-Traitement-de-La-Malaria • https://www.scribd.com/document/318180637/RapportEntre-Oxymetrie-Et-Type-Respiration • https://www.scribd.com/document/315746265/Classificati on-Des-Medicaments • https://www.scribd.com/document/315745909/Incongruen ces-Heresies-et-Heterodoxies-de-la-Notion-deLaboratoire • https://www.scribd.com/document/315745725/RapportEntre-Oxymetrie-Et-Type-Respiration

Itérateur–Générateur–Itérables -57/57mars 2019 (11:25 )

dimanche, 17.

Profile for Jean-Dadet Diasoluka

ITÉRATEUR D'ÉNUMÉRABLES, GÉNÉRATEUR, YIELD ET NEXT  

En simple, on peut dire que 1. yield est une sorte de return qui contrairement à ce dernier ne clôt pas mais suspend/interrompt l’exécution...

ITÉRATEUR D'ÉNUMÉRABLES, GÉNÉRATEUR, YIELD ET NEXT  

En simple, on peut dire que 1. yield est une sorte de return qui contrairement à ce dernier ne clôt pas mais suspend/interrompt l’exécution...

Advertisement