Vous êtes sur la page 1sur 44

1ITÉ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ér ables

J AVA S C R I P T (Programmation Internet) VO 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 va-
riables) 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 sa définition qui
renvoie plutôt un objet à 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 tou-
jours actif (pas terminé).

La 1ère fois que la méthode next() est appelé du générateur, 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 pour à l’objet générateur qui l’a appelé.

Tout comme la commande return, la commande yield renvoie une va-


leur de retour mais dans la propriété .value de l’objet générateur. La
commande return quant à elle renvoie la valeur de retour dans le
propre type de cette dernière.
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI

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.

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. 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 -3/44- vendredi, 21. décembre 2018 (9:57 )


7. Un yield n’est pas obligé d’être dans une boucle.

8. Tout comme return, yield renvoie des valeurs de tout type, pas seu-
lement 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. con-


sole.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 » permet aussi de créer un objet « itérable » :

<script type="text/javascript"> "use strict";


const iterable = {
*[Symbol.iterator]() {
yield "Date() = " + Date();
yield "Date.now() = " + Date.now();
yield "Math.PI = " + Math.PI;
yield "Math.E = " + Math.E;
}
}

for (let i of iterable) {


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

Itération-Générateur-Yield-Next -4/44- vendredi, 21. décembre 2018 (9:57 )


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

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) {
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>

Itérateur-Générateur-Itérables -5/44- vendredi, 21. décembre 2018 (9:57 )


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]);
}
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];
Itération-Générateur-Yield-Next -6/44- vendredi, 21. décembre 2018 (9:57 )
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI

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>

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

Itérateur-Générateur-Itérables -7/44- vendredi, 21. décembre 2018 (9:57 )


.fromCharCode(183)) +
") " +
v+' | ';
console.log(t);
</script>

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ération-Générateur-Yield-Next -8/44- vendredi, 21. décembre 2018 (9:57 )


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érarice :

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 :

let it = genFct(); // Défnition de l’itérateur

it.next(); // Appel du premier yield via « it »


it.next(); // Appel du prochain yield "
it.next(); // Appel du prochain yield "
it.next(); // Appel du prochain yield "

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

Itérateur-Générateur-Itérables -9/44- vendredi, 21. décembre 2018 (9:57 )


yield current++;
}
yield;
} // Fin Définition du générateur

const it = fGenerator();
// Déf itérateur par appel au généateur

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++;
// 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); // 0
console.log(it.next().value); // 1
console.log(it.next().value); // 2
Itération-Générateur-Yield-Next -10/44- vendredi, 21. décembre 2018 (9:57 )
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
console.log(it.next().value); // 1er next Après la boucle
console.log(it.next().value); // undefined
console.log(it.next().value); // undefined
</script>

Et avec la boucle « for ... in » :

<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); // 0
console.log(it.next().value); // 10
console.log(it.next().value); // 20
console.log(it.next().value); // 30
console.log(it.next().value); // undefined
</script>

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); // false
console.log(it.next().value); // true
console.log(it.next().value); // false
console.log(it.next().value); // true
Itérateur-Générateur-Itérables -11/44- vendredi, 21. décembre 2018 (9:57 )
console.log(it.next().value); // undefined
</script>

. next() exécute toujours, et


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 masse herniation un-
defi-ned
}

var it = numeroter();

console.log(it.next().value); // sécrétions
console.log(it.next().value); // lunettes
console.log(it.next().value); // masse
console.log(it.next().value); // herniation
console.log(it.next().value); // undefined
console.log(it.next().value); // undefined
</script>

Une autre façon d’écrire ce même code :

<script type="text/javascript"> "use strict";


function* numeroter(){ // Constructeur
Itération-Générateur-Yield-Next -12/44- vendredi, 21. décembre 2018 (9:57 )
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
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")


// 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],
Object.entries(diag)[c][1]);
// TypeError:
Itérateur-Générateur-Itérables -13/44- vendredi, 21. décembre 2018 (9:57 )
// 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 :


1er La propriété value contient la valeur générée (par yield) et peut être
manipulée librement.
2e Une propriété done qui indique si la boucle de la fonction généra-
trice 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 retour-
né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
// }
//
//
// {…}
// done: false
// value: "Valeur retournée par yield"
// <prototype>: Object { … }

</script>
Itération-Générateur-Yield-Next -14/44- vendredi, 21. décembre 2018 (9:57 )
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI

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, …
// }
// <prototype>: Object { … }
//
//
// 2e niveau de détails (Firefox) :
//
// done: {…}
// configurable: true
// enumerable: true
// value: true
// writable: true
// <prototype>: Object { … }
Itérateur-Générateur-Itérables -15/44- vendredi, 21. décembre 2018 (9:57 )
// 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
//
//
// 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
Itération-Générateur-Yield-Next -16/44- vendredi, 21. décembre 2018 (9:57 )
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
// __proto__: Object
</script>

AFFICHAGE VIA Object.getOwnPropertyNames(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.getOwnPropertyNames(r))

// DANS CONSOLE DE FIREFOX 62.0.2 :


//
// Array [ "value", "done" ]
//
// Un seul (1er) niveau de détails (Firefox) :
//
// (2) […]
// 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)

Itérateur-Générateur-Itérables -17/44- vendredi, 21. décembre 2018 (9:57 )


</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"
];

for (let idx=0;;idx++) {


yield diag[ard[idx]];
}
// sécrétions lunettes masse herniation undefi-
ned
}

var gen = numeroter();

let r;
r=gen.next();
console.log(r.value + " " + r.done); // sécrétions false
r=gen.next();
console.log(r.value + " " + r.done); // lunettes false
r=gen.next();
console.log(r.value + " " + r.done); // masse false
r=gen.next();
console.log(r.value + " " + r.done); // herniation false
r=gen.next();
console.log(r.value + " " + r.done); // undefined false
r=gen.next();
Itération-Générateur-Yield-Next -18/44- vendredi, 21. décembre 2018 (9:57 )
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
console.log(r.value + " " + r.done); // undefined false
</script>

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();

r=gen.next(); console.log(r.value , r.done); // 2 false


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

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

Itérateur-Générateur-Itérables -19/44- vendredi, 21. décembre 2018 (9:57 )


// 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
r=gen.next();
console.log(r.value+" "+r.done); // undefined true
r=gen.next();
console.log(r.value+" "+r.done); // undefined true

// 0 false test.html:21:1
// 1 false test.html:23:1
// 2 false test.html:25:1
// 1er next Après la boucle test.html:10:3
// undefined true test.html:27:1
// undefined true test.html:29:1
// undefined true test.html:31:1
</script>

Ci-dessous aussi, on quitte la boucle quand idx atteint ou dépasse 3


[ for (let idx=0;idx<3;idx++) ]. En ce moment-là aussi, genera-
tor.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"
},

Itération-Générateur-Yield-Next -20/44- vendredi, 21. décembre 2018 (9:57 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
// 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, masse false
// undefined true, undefined true, undefined true
}

var gen = numeroter();

let r;
r=gen.next();
console.log(r.value + " " + r.done); // sécrétions false
r=gen.next();
console.log(r.value + " " + r.done); // lunettes false
r=gen.next();
console.log(r.value + " " + r.done); // masse false
r=gen.next();
console.log(r.value + " " + r.done); // undefined true
r=gen.next();
console.log(r.value + " " + r.done); // undefined true
r=gen.next();
console.log(r.value + " " + r.done); // undefined true

// sécrétions false test.html:28:1


// lunettes false test.html:30:1
// masse false test.html:32:1
// undefined true test.html:34:1
// undefined true test.html:36:1
// undefined true test.html:38:1
</script>

Passation d’arguments à la fonction génératrice :


On peut passer des arguments à la fonction génératrice lors de sa défi-

Itérateur-Générateur-Itérables -21/44- vendredi, 21. décembre 2018 (9:57 )


nition. Ces arguments se comportent dans la fonction génératrice exac-
tement comme les paramètres des fonctions ordinaires. [En passant
signalons que comme d’habitude, il est recommandé de ne jamais mo-
difier 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")
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

Itération-Générateur-Yield-Next -22/44- vendredi, 21. décembre 2018 (9:57 )


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

// 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

// 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 interrom-
pue, 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 retour-
né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. Ke-
liol ») 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);

Itérateur-Générateur-Itérables -23/44- vendredi, 21. décembre 2018 (9:57 )


console.log("*** 2ès instructions");
yield;

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... test.html:3:3


Depuis le généérateur test.html:28:4
*** 1ère Série d'instructions... test.html:6:3
undefined test.html:29:4
2. Baron test.html:7:3
*** 2ès instructions test.html:9:3
undefined test.html:30:4
*** 3ès instructions test.html:12:3
undefined test.html:31:4
4. Kelantina test.html:13:3
*** 4ès instructions test.html:15:3
undefined test.html:32:4

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 terminai-
Itération-Générateur-Yield-Next -24/44- vendredi, 21. décembre 2018 (9:57 )
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
son du générateur. Une fois un générateur terminé, il ne peut plus pro-
duire 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 appe-
lant),
// 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. Ke-
liol...").
// Voir l'ordre d'exécution dans l'affichage de la con-
sole.

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);
}

var gen = Generator();

r=gen.next();
Itérateur-Générateur-Itérables -25/44- vendredi, 21. décembre 2018 (9:57 )
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
// 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
Itération-Générateur-Yield-Next -26/44- vendredi, 21. décembre 2018 (9:57 )
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
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 ren-
contré, 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 con-
sole.log) et continuer l’exécution exactement à l’endroit
où .next() l’a envoyée vers le générateur. L’exécution du pro-
gramme s’y poursuivra jusqu’à rencontrer éventuellement le pro-
chain .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 proposée


à yield, mais ce paramètre n’est plus le même et vaut mainte-
nant la valeur de l’argument du .next() en cours (le
xiè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 test.html:4:6

et retourné un objet générateur avec « value="Initio" » à


l’instruction

Itérateur-Générateur-Itérables -27/44- vendredi, 21. décembre 2018 (9:57 )


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

qui se trouve dans l’appelant et aura affiché :


=> Object { value: " Initio " , done: false } Initio false <= 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 paramètres en cours, ce qui affichera
^^^^^^^ 2. Keliol [2è next] test.html:6:6.

5. Le programme poursuit par la suite son exécution dans le généra-


teur jusqu’au prochain yield ou return. Il croise dans l’entretemps
l’instruction

console . log ( " *** 2ès instructions " ) ;

qu’il exécute en affichant :

*** 2ès instructions 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)),

Itération-Générateur-Yield-Next -28/44- vendredi, 21. décembre 2018 (9:57 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
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éra-
teur, 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 pro-


chain .next() (le troisième) :

r = gen . next ( ' 3 . Baron [ 3è next ] ' ) ;

Le programme rentre donc dans le générateur exactement là où il l’a


quitté, c’est-à-dire à l’instruction

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 " ) ;

Itérateur-Générateur-Itérables -29/44- vendredi, 21. décembre 2018 (9:57 )


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;

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 strict";


var r;
function* autreGen(i) {
yield i * 2; // pour *B*, retourne 30 = 15*2
yield i * 3; // pour *C*, retourne 45 = 15*3
yield i * 4; // pour *D*, retourne 60 = 15*4
}

Itération-Générateur-Yield-Next -30/44- vendredi, 21. décembre 2018 (9:57 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
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*)

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 15
false

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

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

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

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

r=gen.next();
console.log("F**gen ",r.value,r.done); // F**gen 105
false
Itérateur-Générateur-Itérables -31/44- vendredi, 21. décembre 2018 (9:57 )
r=gen.next();
console.log("F**gen ",r.value,r.done); // F**gen undefi-
ned true
// 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éatoi-


rement :

<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" ;
}
}

Itération-Générateur-Yield-Next -32/44- vendredi, 21. décembre 2018 (9:57 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
var gen = Generator();

for(let k=0 ; k<20 ; k++){


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

Exéccution :

.1. pds= 79 kg , taille= 198 cm , imc=31.52 kg²/cm test.html:23:7


.2. pds= 53 kg , taille= 127 cm , imc=22.12 kg²/cm test.html:23:7
.3. pds= 26 kg , taille= 89 cm , imc=7.596 kg²/cm test.html:23:7
.4. pds= 26 kg , taille= 95 cm , imc=7.116 kg²/cm test.html:23:7
.5. pds= 34 kg , taille= 184 cm , imc=6.283 kg²/cm test.html:23:7
.6. pds= 26 kg , taille= 180 cm , imc=3.756 kg²/cm test.html:23:7
.7. pds= 63 kg , taille= 153 cm , imc=25.94 kg²/cm test.html:23:7
.8. pds= 64 kg , taille= 109 cm , imc=37.58 kg²/cm test.html:23:7
.9. pds= 22 kg , taille= 124 cm , imc=3.903 kg²/cm test.html:23:7
10. pds= 74 kg , taille= 88 cm , imc=62.23 kg²/cm test.html:23:7
11. pds= 41 kg , taille= 182 cm , imc=9.236 kg²/cm test.html:23:7
12. pds= 28 kg , taille= 119 cm , imc=6.588 kg²/cm test.html:23:7
13. pds= 34 kg , taille= 171 cm , imc=6.760 kg²/cm test.html:23:7
14. pds= 46 kg , taille= 176 cm , imc=12.02 kg²/cm test.html:23:7
15. pds= 58 kg , taille= 192 cm , imc=17.52 kg²/cm test.html:23:7
16. pds= 36 kg , taille= 190 cm , imc=6.821 kg²/cm test.html:23:7
17. pds= 77 kg , taille= 163 cm , imc=36.37 kg²/cm test.html:23:7
18. pds= 43 kg , taille= 177 cm , imc=10.45 kg²/cm test.html:23:7
19. pds= 51 kg , taille= 149 cm , imc=17.46 kg²/cm test.html:23:7
20. pds= 29 kg , taille= 181 cm , imc=4.646 kg²/cm 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);
}
}
};

for (let member of obj) {

Itérateur-Générateur-Itérables -33/44- vendredi, 21. décembre 2018 (9:57 )


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

Exécution :

1. 2 test.html:12:3
2. 4 test.html:12:3
3. 8 test.html:12:3
4. 16 test.html:12:3
5. 32 test.html:12:3
6. 64 test.html:12:3
7. 128 test.html:12:3
8. 256 test.html:12:3
9. 512 test.html:12:3
10. 1024 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/d8ba19d09334d8e08a1f209fdbacb597
/raw/d96f9bab8f5fbbf5b4d9227f48c73a6848525524/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("")

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

Itération-Générateur-Yield-Next -34/44- vendredi, 21. décembre 2018 (9:57 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
p=res
}

// 2 ^ 0 = 1 test.html:12:23
// 2 ^ 1 = 2 test.html:12:23
// 2 ^ 2 = 4 test.html:12:23
// 2 ^ 3 = 8 test.html:12:23
// 2 ^ 4 = 16 test.html:12:23
// 2 ^ 5 = 32 test.html:12:23
// 2 ^ 6 = 64 test.html:12:23
// 2 ^ 7 = 128 test.html:12:23
// 2 ^ 8 = 256 test.html:12:23
// 2 ^ 9 = 512 test.html:12:23
// 2 ^ 10 = 1024 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) {
return function (c) {
return Math.pow(f(f(b)),2)
}
}
}

for(let k=0;k<=10;k++){
Itérateur-Générateur-Itérables -35/44- vendredi, 21. décembre 2018 (9:57 )
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 ^ 0 = 1
// 2 ^ 1 = 2
// 2 ^ 2 = 4
// 2 ^ 3 = 8
// 2 ^ 4 = 16
// 2 ^ 5 = 32
// 2 ^ 6 = 64
// 2 ^ 7 = 128
// 2 ^ 8 = 256
// 2 ^ 9 = 512
// 2 ^ 10 = 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
// Infinity ^ 2 ^ 2 = Infinity
</script>

Itération-Générateur-Yield-Next -36/44- vendredi, 21. décembre 2018 (9:57 )


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>

Exécution :

Itérateur-Générateur-Itérables -37/44- vendredi, 21. décembre 2018 (9:57 )


0 = 2^-Infinity | 1 = 2^0 | 2 = 2^ 1 |
4 = 2^2 | 8 = 2^ 3 | 16 = 2^ 4 | 32 = 2^ 5 |
64 = 2^ 6 | 128 = 2^ 7 | 256 = 2^ 8 | 512 = 2^ 9 |
1024 = 2^10 | 2048 = 2^11 | 4096 = 2^12 | 8192 = 2^13 |
16384 = 2^14 | 32768 = 2^15 | 65536 = 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 abondam-


ment 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
// 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é.
}
Itération-Générateur-Yield-Next -38/44- vendredi, 21. décembre 2018 (9:57 )
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
// 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("---","***","---");

Ob-
ject.entries(obj).forEach(([cle,val])=>console.log(cle+"
<-> "+val));
// 1 <-> Un
// obj <-> [object Object]
// L <-> A
// deux <-> 2
// array <-> texte,9,[object Object]

// Object.entries(obj) . FOREACH(([CLE])
// object
//
console.log("---","***","---");

Object.entries(obj).forEach(([cle]) =>
console.log(cle));
// 1
Itérateur-Générateur-Itérables -39/44- vendredi, 21. décembre 2018 (9:57 )
// 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)
// 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) {
Itération-Générateur-Yield-Next -40/44- vendredi, 21. décembre 2018 (9:57 )
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
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]

// 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("---","***","---");
Itérateur-Générateur-Itérables -41/44- vendredi, 21. décembre 2018 (9:57 )
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]);
}
// 0 -> D
// 1 -> i
// 2 -> a
// 3 -> s
// 4 -> o
// 5 -> l

// APPLICATIONS PRATIQUES

// HASOWNPROPERTY(prop)
//
console.log("---","***","---");
let triangle = {a: 1, b: 2, c: 3};
let epaisseur = {ep:"epais"};

function ColoredTriangle() {
this.color = 'red';
Itération-Générateur-Yield-Next -42/44- vendredi, 21. décembre 2018 (9:57 )
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
}

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" ]

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));
Itérateur-Générateur-Itérables -43/44- vendredi, 21. décembre 2018 (9:57 )
// 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
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

Itération-Générateur-Yield-Next -44/44- vendredi, 21. décembre 2018 (9:57 )


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

Mots-clés :

Variables statiques, Itération, énumérables, Set, fonction, générateur, itéra-


teur, fonction génératrice, iterator, yield, yield*, next, generator, construc-
tibles, curry, currying, closures, fermetures, curries, curryfication, boucle,
test conditionnel, javascript, opérateur new, ECMA, ECMASCRIPT, argu-
ments, paramètres.

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

Itérateur-Générateur-Itérables -45/44- vendredi, 21. décembre 2018 (9:57 )

Vous aimerez peut-être aussi