Vous êtes sur la page 1sur 14

J.B.

Dadet DIASOLUKA Luyalu Nzoyifuanga


JA V ASCRIPT (ProgrammationInternet)VOL. VI
+243 - 851278216 - 899508675 - 995624714 - 902263541 - 813572818
La dernière révision de ce texte est disponible sur CD.

CHAPITRE 12 : Les fonctions imbriquées en javascript

Contrairement aux langages CC, en JavaScript les fonctions


peuvent être imbriquées . Ceci parce qu’en JavaScript les
fonctions sont des « objets de premier ordre » on dit aus-
si « objets de première classe » car elles peuvent être
manipulées, échangées, avoir des propriétés et des métho-
des, 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 appe-
lée que du sein de la fonction qui l’englobe
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
</script>

Les membres d’une fonction ont une portée/visibilité lo-


cale (limitée au bloc de cette fonction) : pas accessibles
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
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".toUpper-
Case())
}
else if(sx.startsWith("F")) {
console.log(msg,"la ménopause".toUpper-
Case())
}
else {
console.log("Sexe Vide.".toUpperCase())
}
}
}

/////////////////////////////////
recommendation(gender);
/////////////////////////////////
}

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é) por-
Fonctions Imbriquées - 2 / 14 - mardi, 10. juillet 2018 (10:07 pm)
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
tant le même nom que la fonction englobante, cette pro-
priété servira de « clé » pour accéder à la fonction im-
briquée, sans le mot-clé var
var.ni le mot-clé this
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".toUp-
perCase())
}
else if(sx.startsWith("F")) {
console.log(msg,"la ménopause".toUpper-
Case())
}
else {
console.log("Sexe Vide.".toUpperCase())
}
}
}

/////////////////////////////////
personne.rec = recommandation;
/////////////////////////////////
}

personne(1953);
personne.rec("Homme");
// Attention! Âge [65] > 50 ans! Veillez à L'ANDRO-
PAUSE
</script>

Une autre façon d’appeler la fonction imbriquée du dehors


de la fonction englobante est de faire de la fonction im-
briquée une méthode de la fonction englobante, avec le
Fonctions Imbriquées - 3 / 14 - mardi, 10. juillet 2018 (10:07 pm)
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
mot-clé this
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
propriét
constructeur, du sein de ses instances
instances.
// Mais vous ne pouvez accéder à une variable locale
que du sein de la fonction (ici le constructeur
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".toUp-
perCase())
}
else if(sx.startsWith("F")) {
console.log(msg,"la ménopause".toUpper-
Case())
}
else {
console.log("Sexe Vide.".toUpperCase())
}
}
}
}

const inst = new personne(1953);


inst.recommandation("Femme");
// Attention! Âge 65 > 50 ans! Veillez à LA MÉNO-
PAUSE
</script>

Fonctions Imbriquées - 4 / 14 - mardi, 10. juillet 2018 (10:07 pm)


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
Au besoin, vous pouvez utiliser la technique de curry
function
function, on parle alors de fermeture (= closure
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".toUpper-
Case())
}
else if(sx.startsWith("F")) {
console.log(msg,"la ménopause".toUpper-
Case())
}
else {
console.log("Sexe Vide.".toUpperCase())
}
}
}

/////////////////////////////////
return recommendation;
/////////////////////////////////
}

let emissaire=personne(1953);
var rec = emissaire("Homme")
// Attention! Âge 65 > 50 ans! Veillez à L'ANDRO-
PAUSE

var rec = emissaire("Femme")


// Attention! Âge 65 > 50 ans! Veillez à LA MÉNO-
PAUSE

var rec = emissaire("")


// SEXE VIDE.
</script>

Fonctions Imbriquées - 5 / 14 - mardi, 10. juillet 2018 (10:07 pm)


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

Vous pouvez aussi appeler la fonction englobante et la


fonction imbriquée dans une même instruction
instruction, par une suc-
cession 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! Veil-
lez à";

if(age>=(L=50)){
if(sx.toLowerCase().startsWith("m") ||
sx.toLowerCase().startsWith("h")) {
console.log(msg,"l'andropause".toUpper-
Case())
}
else if(sx.startsWith("F")) {
console.log(msg,"la ménopause".toUpper-
Case())
}
else {
console.log(msg,"...Sexe Vide.".toUpper-
Case())
}
}
else console.log(msg,"...VoTrE jeUnesSe.".toUp-
perCase())
}

return recommendation;
}

let emissaire;
/////////////////////////////////
emissaire=personne(1963)("Homme")
// Attention! Âge 55 >= 50 ans! Veillez à L'ANDRO-
PAUSE

emissaire=personne(1973)("Mâle")
Fonctions Imbriquées - 6 / 14 - mardi, 10. juillet 2018 (10:07 pm)
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
// 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ÉNO-
PAUSE

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>

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".toUpper-
Case())
}
Fonctions Imbriquées - 7 / 14 - mardi, 10. juillet 2018 (10:07 pm)
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
else if(sx.startsWith("F")) {
console.log(msg,"la ménopause".toUpper-
Case())
}
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'AN-
DROPAUSE

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.getOwnPropertyDescrip-


tors( emissaire) »:
tors(emissaire)

<script language="JavaScript"> "use strict";


function personne(dn,gender){
let age=(new Date()).getFullYear() - dn

function recommendation(sx){
if(!sx) sx="";
Fonctions Imbriquées - 8 / 14 - mardi, 10. juillet 2018 (10:07 pm)
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
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".toUpper-
Case())
}
else if(sx.startsWith("F")) {
console.log(msg,"la ménopause".toUpper-
Case())
}
else {
console.log("Sexe Vide.".toUpperCase())
}
}
}

/////////////////////////////////
return [recommendation , age];
/////////////////////////////////
}

let emissaire=personne(1953);
console.dir(Object.getOwnPropertyDescriptors(emis-
saire))
//
// Object
A 0:{value: ƒ, writable: true, enumerable: true, confi-
gurable: true}
B 1:{value: 65, writable: true, enume-
rable: true, configurable: true}
C length:{value: 2, writable: true, enume-
rable: 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){
Fonctions Imbriquées - 9 / 14 - mardi, 10. juillet 2018 (10:07 pm)
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
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".toUpper-
Case())
}
else if(sx.startsWith("F")) {
console.log(msg,"la ménopause".toUpper-
Case())
}
else {
console.log("Sexe Vide.".toUpperCase())
}
}
}

/////////////////////////////////
return [recommendation , age];
/////////////////////////////////
}

let emissaire=personne(1953);
for(const key in emissaire) console.log(key, emis-
saire[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


Fonctions Imbriquées - 10 / 14 - mardi, 10. juillet 2018 (10:07 pm)
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
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")) {
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())
Fonctions Imbriquées - 11 / 14 - mardi, 10. juillet 2018 (10:07 pm)
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
// Object { value: undefined, done: true }
</script>

I. Quant à appeler une fonction en cliquant un lien, il y a deux


possibilités :

1. L’hypertexte sert seulement à appeler une fonction. La chose est


alors très facile :

<a href="javascript:
console.dir(Object.getOwnPropertyDescriptors(HTMLDi-
vElement))">
Without Following Link
</a>

2. 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(Docu-
ment));
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
Fonctions Imbriquées - 12 / 14 - mardi, 10. juillet 2018 (10:07 pm)
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-VI
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(Docu-
ment));
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(Docu-
ment));
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, 10. juillet 2018 (10:07 pm).

Fonctions Imbriquées - 13 / 14 - mardi, 10. juillet 2018 (10:07 pm)


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

DIASOLUKANz. 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 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 - 14 / 14 - mardi, 10. juillet 2018 (10:07 pm)