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

Transcription

ITÉRATEUR D'ÉNUMÉRABLES, GÉNÉRATEUR, YIELD ET NEXT
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ér ables
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 ».
En fait tout se passe comme si (et c’est ainsi) « next » parcourt l’un
après l’autre les éléments de l’itérable en incrémentant l’indexeur.
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
Illustration et comparaison :
I. VERSION STRING
<script type = "text/javascript"> "use strict";
const s = "diasoluka";
// Chaîne
let a = Array.from(s) ,
// Array
i = 0;
// index
do {
console.log(`s : ${a[i++]}`)
} while (i < a.length);
</script>
<script type = "text/javascript"> "use strict";
console.log("=".repeat(15));
</script>
II. VERSION PROTOCOLES D'ITÉRATION
<script type = "text/javascript"> "use strict";
let alias;
const si = "diasoluka";
// Chaîne
var ii = si [Symbol.iterator]();
// Équivaut à
//
let a = Array.from(s) ,
// Array
//
ii = 0;
// index
while(alias = ii.next() , ! alias.done){
console.log(`it = ${alias.value}`)
};
// Cette boucle while() équivaut à
//
do {
//
console.log(`s : ${a[i++]}`)
//
} while (i < a.length);
</script>
N.B. : Un « objet itérateur » est créé sans l’opérateur « new ».
Itérateur–Générateur–Itérables
-3/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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>
Itérateur–Générateur–Itérables
-4/54-
dimanche, 14. avril 2019 (4:16 )
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. 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/54-
dimanche, 14. avril 2019 (4:16 )
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 » 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);
console.log([...iterable])
</script>
Itérateur–Générateur–Itérables
-6/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
Une autre façon légèrement différente d’écrire le code ci-dessus :
<script type="text/javascript"> "use strict";
const iterable = new Object();
iterable[Symbol.iterator] = function* () {
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);
console.log([...iterable])
</script>
Itérateur–Générateur–Itérables
-7/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
<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.
for (const [id,svce] of repSces(diags[c++])) {
// Retourner [cle,val] pour chaque couple d'un
// membre de diags.
Itérateur–Générateur–Itérables
-8/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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) {
if(k=="tartre") flagt++;
if(k=="crouzon") flagc++;
yield ++c+". "+k;
}
}
}
Itérateur–Générateur–Itérables
-9/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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]);
}
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>
Itérateur–Générateur–Itérables
-10/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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
-11/54-
dimanche, 14. avril 2019 (4:16 )
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>
Et avec des lettres :
<script type="text/javascript"> "use strict";
const a1 = ["L", "U", "Y"],
Itérateur–Générateur–Itérables
-12/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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>
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
Itérateur–Générateur–Itérables
-13/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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
"
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
Itérateur–Générateur–Itérables
-14/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
« 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);
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",
Itérateur–Générateur–Itérables
-15/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
"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",
"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>
Itérateur–Générateur–Itérables
-16/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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);
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
Itérateur–Générateur–Itérables
-17/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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
yield retourne une valeur de n’importe quel type, dans la propriété « value » de l’itérateur.
<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]];
Itérateur–Générateur–Itérables
-18/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
}
// sécrétions
defi-ned
}
JavaScript Tome-VI
lunettes
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;
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"
};
Itérateur–Générateur–Itérables
-19/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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:
// 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() {
Itérateur–Générateur–Itérables
-20/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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>
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) :
{…}
Itérateur–Générateur–Itérables
-21/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
//
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 { … }
//
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: {
Itérateur–Générateur–Itérables
-22/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
//
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
// __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" ]
//
Itérateur–Générateur–Itérables
-23/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
// 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)
</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/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
for (let idx=0;;idx++) {
yield diag[ard[idx]];
}
// sécrétions
lunettes
ned
}
JavaScript Tome-VI
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();
r=gen.next(); console.log(r.value , r.done); // 2
r=gen.next(); console.log(r.value , r.done); // 1
r=gen.next(); console.log(r.value , r.done); // 0
Itérateur–Générateur–Itérables
-25/54-
false
false
false
dimanche, 14. avril 2019 (4:16 )
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
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
// 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); //
r=gen.next();
console.log(r.value+" "+r.done); //
r=gen.next();
console.log(r.value+" "+r.done); //
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); //
r=gen.next();
console.log(r.value+" "+r.done); //
Itérateur–Générateur–Itérables
-26/54-
0 false
1 false
2 false
undefined true
undefined true
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
// 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 moment-là 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
}
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
Itérateur–Générateur–Itérables
-27/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
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
JavaScript Tome-VI
+ " " + r.done); // masse false
+ " " + r.done); // undefined true
+ " " + r.done); // undefined true
+ " " + r.done); // undefined true
// sécrétions false
// lunettes false
// masse false
// undefined true
// undefined true
// undefined true
</script>
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")
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;
Itérateur–Générateur–Itérables
-28/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
}
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
// 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>
Itérateur–Générateur–Itérables
-29/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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;
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);
Itérateur–Générateur–Itérables
-30/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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
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.
Itérateur–Générateur–Itérables
-31/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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();
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
Itérateur–Générateur–Itérables
-32/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
//
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
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
Itérateur–Générateur–Itérables
-33/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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 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
test.html:4:6
et retourné un objet générateur avec « value="Initio" » à
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 cidessous :
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 ] ' ».
Itérateur–Générateur–Itérables
-34/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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érateur
jusqu’au prochain yield ou return. Il croise dans l’entretemps
l’instruction
console . log ( " *** 2ès instructions " ) ;
qu’il
exécute
en
*** 2ès instructions
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) :
r = gen . next ( ' 3 . Baron [ 3è next ] ' ) ;
Le programme rentre donc dans le générateur exactement là où il l’a
Itérateur–Générateur–Itérables
-35/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
quitté,
JavaScript Tome-VI
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 " ) ;
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
Itérateur–Générateur–Itérables
-36/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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*)
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
Itérateur–Générateur–Itérables
-37/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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
ned true
// undefined : il n'y a plus de yield dans gen.
</script>
undefi-
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éatoiItérateur–Générateur–Itérables
-38/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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" ;
}
}
var gen = Generator();
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.
pds=
pds=
pds=
pds=
pds=
pds=
pds=
pds=
pds=
pds=
pds=
79
53
26
26
34
26
63
64
22
74
41
kg
kg
kg
kg
kg
kg
kg
kg
kg
kg
kg
,
,
,
,
,
,
,
,
,
,
,
taille=
taille=
taille=
taille=
taille=
taille=
taille=
taille=
taille=
taille=
taille=
198
127
89
95
184
180
153
109
124
88
182
Itérateur–Générateur–Itérables
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
-39/54-
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
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
12.
13.
14.
15.
16.
17.
18.
19.
20.
pds=
pds=
pds=
pds=
pds=
pds=
pds=
pds=
pds=
28
34
46
58
36
77
43
51
29
kg
kg
kg
kg
kg
kg
kg
kg
kg
,
,
,
,
,
,
,
,
,
taille=
taille=
taille=
taille=
taille=
taille=
taille=
taille=
taille=
119
171
176
192
190
163
177
149
181
cm
cm
cm
cm
cm
cm
cm
cm
cm
JavaScript Tome-VI
,
,
,
,
,
,
,
,
,
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
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);
}
}
};
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
Itérateur–Générateur–Itérables
-40/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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) )
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
// 2 ^ 2
// 4 ^ 2
=
=
=
=
=
=
=
=
=
=
=
=
=
1
2
4
8
16
32
64
128
256
512
= 1024
2
4
16
Itérateur–Générateur–Itérables
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
test.html:18:3
test.html:18:3
test.html:18:3
-41/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
// 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++){
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
^
^
^
^
^
^
0
1
2
3
4
5
=
=
=
=
=
=
1
2
4
8
16
32
Itérateur–Générateur–Itérables
-42/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
//
//
//
//
//
2
2
2
2
2
^
^
^
^
^
6
7
8
9
10
=
=
=
=
JavaScript Tome-VI
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
// Infinity ^ 2 ^ 2 = Infinity
</script>
Itérateur–Générateur–Itérables
-43/54-
dimanche, 14. avril 2019 (4:16 )
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
-44/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
0
= 2^-Infinity
4 = 2^2
|
8
64 = 2^ 6 |
128
1024 = 2^10 | 2048
16384 = 2^14 | 32768
=
=
=
=
JavaScript Tome-VI
|
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
// console.log()
// « objet. » est un littéral arbitraire
// ${prop} donne le nom (clé) de la propriété,
Itérateur–Générateur–Itérables
-45/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
// ${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]
// Object.entries(obj) . FOREACH(([CLE])
// object
//
console.log("---","***","---");
Object.entries(obj).forEach(([cle]) =>
Itérateur–Générateur–Itérables
-46/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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)
// object
//
console.log("---","***","---");
console.log(Object.values(obj));
// Array [ "Un", {}, "A", 2, […] ]
// FOR (var idx IN obj.array) {
// array
Itérateur–Générateur–Itérables
-47/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
//
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]
// 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)
Itérateur–Générateur–Itérables
-48/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
// 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]);
}
// 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};
Itérateur–Générateur–Itérables
-49/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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" ]
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("---","***","---");
Itérateur–Générateur–Itérables
-50/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
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
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
Itérateur–Générateur–Itérables
-51/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
--- *** --- test.html:260:3
*** OWN PROP : ColoredTriangle.aimepar = 15 test.html:262:5
Kinshasa, le dimanche 14 avril 2019 - 4:16:35 AM
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
-52/54-
dimanche, 14. avril 2019 (4:16 )
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
[email protected]
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/LeItérateur–Générateur–Itérables
-53/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
Hasard-Des-Thermometres-Non-contact-a-Infrarouge
• https://www.scribd.com/document/376222482/PetiteIntroduction-Aux-Fonctions-JavaScript
• 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/motiliteItérateur–Générateur–Itérables
-54/54-
dimanche, 14. avril 2019 (4:16 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
oculaire-2
• https://www.scribd.com/document/355291239/motiliteoculaire-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
-55/54-
dimanche, 14. avril 2019 (4:16 )