javascript tome vi - fonctions imbriquees en JS

advertisement
J.B. Dadet DIASOLUKA Luyalu Nzoyifuanga
J AVA S C R I P T (Programmation Internet) V O L . V I
+243 - 851278216 - 899508675 - 995624714 - 902263541 - 813572818
La dernière révision de ce texte est disponible sur CD.
CHAPITRE 12 : L e s f o n c t i o n s i m b r i q u é e s e n j a v a s c r i p t
Contrairement aux langages C, en JavaScript les fonctions
peuvent être imbriquées . Ceci parce qu’en JavaScript les
fonctions sont des « objets de premier ordre « on dit
aussi « objets de première classe « car elles peuvent
être manipulées, échangées, avoir des propriétés et des
méthodes, comme tout autre objet JS. Une fonction JS, ordinaire soit-elle, est donc ni plus ni moins un objet
Function (callable object). Or justement les méthodes sont
ni plus ni moins des fonctions.
Mais une fonction imbriquée ne peut en principe être appelée que du sein de la fonction qui l’englobe.
<script language="JavaScript"> "use strict";
function personne(){
function recommendation(){
console.log( "Hello");
}
}
console.log(personne());
// undefined
//console.log(recommandation());
// Uncaught ReferenceError:
//
recommandation is not defined
console.log(personne.recommandation());
// Uncaught TypeError:
//
personne.recommandation is not a function
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
</script>
Les membres d’une fonction ont une portée/visibilité locale (limitée au bloc de cette fonction) : pas accessibles
du dehors de la fonction.
Vous pouvez normalement vous arranger pour éventuellement
appeler la fonction imbriquée seulement du sein-même de la
fonction englobante. Vous l’exécutez bien s«r, mais pas
du dehors de la fonction englobante.
<script language="JavaScript"> "use strict";
function personne(dn,gender){
let age=(new Date()).getFullYear() - dn
function recommendation(sx){
if(!sx) sx="";
if(age>50){
const msg="Attention! Âge "+age+" > 50 ans!
Veillez Â";
if(sx.toLowerCase().startsWith("m") ||
sx.toLowerCase().startsWith("h")) {
console.log(msg,"l'andropause".toUpperCase())
}
else if(sx.startsWith("F")) {
console.log(msg,"la mÂnopause".toUpperCase())
}
else {
console.log("Sexe Vide.".toUpperCase())
}
}
}
/////////////////////////////////
recommendation(gender);
/////////////////////////////////
}
Fonctions Imbriquées
- 2 / 15 -
mardi, 2. octobre 2018 (12:02 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
personne(1953,"");
// SEXE VIDE.
</script>
Une fa«on de contourner cette restriction est de créer au
sein de la fonction englobante un membre (propriété) portant le même nom que la fonction englobante, cette propriété servira de « clé « pour accéder à la fonction
imbriquée, sans le mot-clé var.ni le mot-clé this.
<script language="JavaScript"> "use strict";
function personne(dn){
let age=(new Date()).getFullYear() - dn
function recommandation(sx){
if(!sx) sx="";
if(age>50){
const msg="Attention! Âge "+age+" > 50 ans!
Veillez Â";
if(sx.toLowerCase().startsWith("m") ||
sx.toLowerCase().startsWith("h")) {
console.log(msg,"l'andropause".toUpperCase())
}
else if(sx.startsWith("F")) {
console.log(msg,"la mÂnopause".toUpperCase())
}
else {
console.log("Sexe Vide.".toUpperCase())
}
}
}
/////////////////////////////////
personne.rec = recommandation;
/////////////////////////////////
}
personne(1953);
Fonctions Imbriquées
- 3 / 15 -
mardi, 2. octobre 2018 (12:02 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
personne.rec("Homme");
// Attention! Âge [65] > 50 ans! Veillez  L'ANDROPAUSE
</script>
Une autre fa«on d’appeler la fonction imbriquée du dehors de la fonction englobante est de faire de la fonction
imbriquée une méthode de la fonction englobante, avec le
mot-clé this. Ensuite créer une instance de la fonction
englobante, et appeler la fonction imbriquée comme méthode
de l’instance.
<script language="JavaScript"> "use strict";
function personne(dn){
let age=(new Date()).getFullYear() - dn
// age === var locale, pas propriÂtÂ
/*
// Vous pouvez accÂder  une propriÂt en dehors du
constructeur, du sein de ses instances.
// Mais vous ne pouvez accÂder  une variable locale
que du sein de la fonction (ici le constructeur).
*/
this.recommandation = function(sx){
if(!sx) sx="";
if(age>50){
const msg="Attention! Âge "+age+" > 50 ans!
Veillez Â";
if(sx.toLowerCase().startsWith("m") ||
sx.toLowerCase().startsWith("h")) {
console.log(msg,"l'andropause".toUpperCase())
}
else if(sx.startsWith("F")) {
console.log(msg,"la mÂnopause".toUpperCase())
}
else {
console.log("Sexe Vide.".toUpperCase())
Fonctions Imbriquées
- 4 / 15 -
mardi, 2. octobre 2018 (12:02 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
}
}
}
}
const inst = new personne(1953);
inst.recommandation("Femme");
// Attention! Âge 65 > 50 ans! Veillez  LA MÂNOPAUSE
</script>
Au besoin, vous pouvez utiliser la technique de curry
function, on parle alors de fermeture (= closure):
<script language="JavaScript"> "use strict";
function personne(dn,gender){
let age=(new Date()).getFullYear() - dn
function recommendation(sx){
if(!sx) sx="";
if(age>50){
const msg="Attention! Âge "+age+" > 50 ans!
Veillez Â";
if(sx.toLowerCase().startsWith("m") ||
sx.toLowerCase().startsWith("h")) {
console.log(msg,"l'andropause".toUpperCase())
}
else if(sx.startsWith("F")) {
console.log(msg,"la mÂnopause".toUpperCase())
}
else {
console.log("Sexe Vide.".toUpperCase())
}
}
}
/////////////////////////////////
return recommendation;
Fonctions Imbriquées
- 5 / 15 -
mardi, 2. octobre 2018 (12:02 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
/////////////////////////////////
}
let emissaire=personne(1953);
var rec = emissaire("Homme")
// Attention! Âge 65 > 50 ans! Veillez  L'ANDROPAUSE
var rec = emissaire("Femme")
// Attention! Âge 65 > 50 ans! Veillez  LA MÂNOPAUSE
var rec = emissaire("")
// SEXE VIDE.
</script>
Vous pouvez aussi appeler la fonction englobante et la
fonction imbriquée dans une même instruction, par une succession de parenthèses :
<script language="JavaScript"> "use strict";
function personne(dn,gender){
let age=(new Date()).getFullYear() - dn
function recommendation(sx){
if(!sx) sx="";
let L=50;
const msg="Attention! Âge "+age+
` ${age>=50?'>=':'<'} ` + L+" ans! Veillez Â";
if(age>=(L=50)){
if(sx.toLowerCase().startsWith("m") ||
sx.toLowerCase().startsWith("h")) {
console.log(msg,"l'andropause".toUpperCase())
}
else if(sx.startsWith("F")) {
console.log(msg,"la mÂnopause".toUpperCase())
}
Fonctions Imbriquées
- 6 / 15 -
mardi, 2. octobre 2018 (12:02 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
else {
console.log(msg,"...Sexe
Vide.".toUpperCase())
}
}
else console.log(msg,"...VoTrE jeUnesSe.".toUpperCase())
}
return recommendation;
}
let emissaire;
/////////////////////////////////
emissaire=personne(1963)("Homme")
// Attention! Âge 55 >= 50 ans! Veillez  L'ANDROPAUSE
emissaire=personne(1973)("MÂle")
// Attention! Âge 45 < 50 ans! Veillez  ...VOTRE
JEUNESSE.
emissaire=personne(1953)("")
// Attention! Âge 65 >= 50 ans! Veillez  ...SEXE
VIDE.
emissaire=personne(1919)("Femelle")
// Attention! Âge 99 >= 50 ans! Veillez  LA MÂNOPAUSE
emissaire=personne(1969)()
// Attention! Âge 49 < 50 ans! Veillez  ...VOTRE
JEUNESSE.
emissaire=personne(1968 , "Femme")()
// Attention! Âge 50 >= 50 ans! Veillez  ...SEXE
VIDE.
emissaire=personne()("Femme",1923)
// Attention! Âge NaN < 50 ans! Veillez  ...VOTRE
JEUNESSE.
/////////////////////////////////
</script>
Fonctions Imbriquées
- 7 / 15 -
mardi, 2. octobre 2018 (12:02 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
Vous pouvez aussi faire en sorte de n’appeler la fonction
« recommandation « que sous certaines conditions selon
le statu renvoyé par la fonction englobante.
<script language="JavaScript"> "use strict";
function personne(dn,gender){
let age=(new Date()).getFullYear() - dn
function recommendation(sx){
if(!sx) sx="";
if(age>50){
const msg="Attention! Âge "+age+" > 50 ans!
Veillez Â";
if(sx.toLowerCase().startsWith("m") ||
sx.toLowerCase().startsWith("h")) {
console.log(msg,"l'andropause".toUpperCase())
}
else if(sx.startsWith("F")) {
console.log(msg,"la mÂnopause".toUpperCase())
}
else {
console.log("Sexe Vide.".toUpperCase())
}
}
}
/////////////////////////////////
return [recommendation , age];
/////////////////////////////////
}
let emissaire=personne(1953);
if(emissaire[1]>50) {
var rec = emissaire[0]("")
// SEXE VIDE.
var rec = emissaire[0]("Homme")
// Attention! Âge 65 > 50 ans! Veillez  L'ANDROPAUSE
Fonctions Imbriquées
- 8 / 15 -
mardi, 2. octobre 2018 (12:02 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
var rec = emissaire[0]("Femme")
// Attention! Âge 65 > 50 ans! Veillez  LA MÂNOPAUSE
}
</script>
Voyons dans ce dernier cas l’anatomie (la configuration
interne) de la variable array « emissaire « :
Avec la propriété «
Object.getOwnPropertyDescriptors(emissaire)
«:
<script language="JavaScript"> "use strict";
function personne(dn,gender){
let age=(new Date()).getFullYear() - dn
function recommendation(sx){
if(!sx) sx="";
if(age>50){
const msg="Attention! Âge "+age+" > 50 ans!
Veillez Â";
if(sx.toLowerCase().startsWith("m") ||
sx.toLowerCase().startsWith("h")) {
console.log(msg,"l'andropause".toUpperCase())
}
else if(sx.startsWith("F")) {
console.log(msg,"la mÂnopause".toUpperCase())
}
else {
console.log("Sexe Vide.".toUpperCase())
}
}
}
/////////////////////////////////
return [recommendation , age];
/////////////////////////////////
}
Fonctions Imbriquées
- 9 / 15 -
mardi, 2. octobre 2018 (12:02 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
let emissaire=personne(1953);
console.dir(Object.getOwnPropertyDescriptors(emissaire))
//
// Object
A
0:{value: ƒ, writable: true, enumerable: true, config
urable: true}
B
1:{value: 65, writable: true, enumerable: true, confi
gurable: true}
C
length:{value: 2, writable: true, enumerable: false,
configurable: false}
D
__proto__:Object
</script>
On peut aussi parcourir (énumérer) les propriétés de
l’array « emissaire « avec la commande « for ...
in « :
<script language="JavaScript"> "use strict";
function personne(dn,gender){
let age=(new Date()).getFullYear() - dn
function recommendation(sx){
if(!sx) sx="";
if(age>50){
const msg="Attention! Âge "+age+" > 50 ans!
Veillez Â";
if(sx.toLowerCase().startsWith("m") ||
sx.toLowerCase().startsWith("h")) {
console.log(msg,"l'andropause".toUpperCase())
}
else if(sx.startsWith("F")) {
console.log(msg,"la mÂnopause".toUpperCase())
}
else {
console.log("Sexe Vide.".toUpperCase())
}
Fonctions Imbriquées
- 10 / 15 -
mardi, 2. octobre 2018 (12:02 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
}
}
/////////////////////////////////
return [recommendation , age];
/////////////////////////////////
}
let emissaire=personne(1953);
for(const key in emissaire) console.log(key, emissaire[key])
/*
0
ƒ recommendation(sx){
if(!sx) sx="";
if(age>50){
const msg="Attention! Âge "+age+" > 50 ans!
Veillez Â";
if(sx.toLowerCase().startsWith("m") ||
sx.toLowerCase(…
1
65
*/
</script>
Maintenant, parcourons l’array retourn e, avec un
IT RATEUR :
<script language="JavaScript"> "use strict";
function personne(dn,gender){
let age=(new Date()).getFullYear() - dn
function recommendation(sx){
if(!sx) sx="";
if(age>50){
const msg="Attention! Âge "+age+" > 50 ans!
Veillez Â";
if(sx.toLowerCase().startsWith("m") ||
sx.toLowerCase().startsWith("h")) {
console.log(msg,"l'andropause".toUpperCase())
}
else if(sx.startsWith("F")) {
Fonctions Imbriquées
- 11 / 15 -
mardi, 2. octobre 2018 (12:02 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
console.log(msg,"la
mÂnopause".toUpperCase())
}
else {
console.log("Sexe Vide.".toUpperCase())
}
}
}
/////////////////////////////////
return [recommendation , age];
/////////////////////////////////
}
let ITERABLE=personne(1953);
const ITERATOR = ITERABLE[Symbol.iterator]();
for(let key in
ITERABLE)console.log(ITERATOR.next())
/*
Object { value: recommendation(), done: false }
Object { value: 65, done: false }
*/
console.log(ITERATOR.next())
// Object { value: undefined, done: true }
console.log(ITERATOR.next())
// Object { value: undefined, done: true }
</script>
I. Quant à appeler une fonction en cliquant un lien, il y a deux
possibilitàs :
1er L’hypertexte sert seulement à appeler une fonction. La chose est
alors tràs facile :
<a href="javascript:
console.dir(Object.getOwnPropertyDescriptors(HTMLDivE
lement))">
Without Following Link
Fonctions Imbriquées
- 12 / 15 -
mardi, 2. octobre 2018 (12:02 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
</a>
2e L’hypertexte DOIT APPELER une fonction mais aussi jouer son
ràle habituel, c’est-à-dire « suivre le lien » = aller à un
emplacement spàcifique de la page en cours ou ouvrir la page
pointàe. Les choses sont alors un peu corsàes, mais encore
toujours facile :
<a
href="javascript:my_func('http://diasmath.blogg.org')
">
Following Link
</a>
<script language="JavaScript">
function my_func(s) {
console.dir(Object.getOwnPropertyDescriptors(Document
));
window.open(s)
}
</script>
II. Si l’hypertexte doit àtre activà par l’àvànement « onclick » pour
appeler une fonction externe à l’àlàment ou exàcuter un javascript
local, son « href » doit àtre une simple di se , qu’il doive ou pas
suivre de lien.
<a href="#"
onclick="javascript:my_func('http://diasmath.blogg.or
g')">
Lien DiÂse
</a>
<script language="JavaScript">
function my_func(s) {
console.dir(Object.getOwnPropertyDescriptors(Document
));
Fonctions Imbriquées
- 13 / 15 -
mardi, 2. octobre 2018 (12:02 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-VI
window.open(s)
}
</script>
Parfois aussi àa marche sans le mot-clà « javascript» :
<a href="#"
onclick="my_func('http://diasmath.blogg.org')">
Lien DiÂse
</a>
<script language="JavaScript">
function my_func(s) {
console.dir(Object.getOwnPropertyDescriptors(Document
));
window.open(s)
}
</script>
Mots-cl s :
fonctions imbriquàes, objets de premiàre classe, objet Function,
callable object, objets de premier ordre, objets de premiàre classe,
fonction englobante, variable locale, instances, constructeur, curry,
fermeture, closure, getOwnPropertyDescriptors, hypertexte
mardi, 2. octobre 2018 (12:02 ).
Fonctions Imbriquées
- 14 / 15 -
mardi, 2. octobre 2018 (12:02 )
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)
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 - 995624714 - 902263541 - 813572818
diasfb mail2world.com
Fonctions Imbriquées
- 15 / 15 -
mardi, 2. octobre 2018 (12:02 )
Téléchargement