javascript tome vi - this & fonctions PAS PRET
Transcription
javascript tome vi - this & fonctions PAS PRET
This & Functions J AVA S C R I P T (Programmation Internet) V O L . I V Po u r D é b u t e r J.B. Dadet DIASOLUKA Luyalu Nzoyifuanga +243 - 851278216 - 899508675 - 991239212 - 902263541 - 813572818 La dernière révision de ce texte est disponible sur CD. « Event » (Événement) on associe fréquemment une fonction anonyme a un évènement crée dynamiquement. , document.getElementById('mon_element').onclick = function(param1,param2,event,this){ du code du code} document.getElementById('mon_element').addEventListener('click', function(param1,param2,,this){ du code du code}, false); Déclaration de fonction avec variable Au lieu de déclarer une fonction en lui attribuant un nom on va faire l'inverse en déclarant une variable et en lui attribuant une fonction anonyme <script type="text/javascript"> "use strict"; var funcID = function () { code }; </script> Pour lancer la fonction il suffira d'appeler la variable en ajoutant les parenthèses afin d’exécuter le contenu de la variable. funcID (); J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV IIFE (Immediately Invoked Function Expression) l'IIFE permet de créer un espace de travail afin d’éviter le scope de variable au sein d'une page pour ce faire au chargement de la page on lance l'exécution d'une fonction anonyme qui est conservé en mémoire. (function() { Le code de la fonction ici })(); Fonctions fléchées Les paramètres d'une fonction Il est possible de passer des paramètres à une fonction, c'est-à-dire lui fournir une valeur ou le nom d'une variable afin que la fonction puisse effectuer des opérations sur ces paramètres ou bien grâce à ces paramètres. Lorsque vous passez plusieurs paramètres à une fonction il faut les séparer par des virgules, aussi bien dans la déclaration que dans l'appel et il faudra veiller à bien passer le bon nombre de paramètres lors de l'appel au risque sinon de créer une erreur dans votre Javascript... Imaginons que l'on veuille créer une page Web qui affiche une boîte de dialogue (les boîtes de dialogues sont à éviter dans vos pages car elles sont énervantes, mais c'est toutefois une manière simple d'apprendre le Javascript) qui affiche un texte différent selon le lien sur lequel on appuie. Variables & Functions 2 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV La méthode de base consiste à faire une fonction pour chaque texte à afficher : <HTML> <HEAD> <SCRIPT language="Javascript"> function Affiche1() { alert('Texte 1'); } function Affiche2() { alert('Texte2'); } </SCRIPT> </HEAD> <BODY> <A href="javascript:;" onClick="Affiche1();">Texte1</A> <A href="javascript:;" onClick="Affiche2();">Texte2</A> </BODY> </HTML> Ce qui donne ceci : Il existe toutefois une methode plus "classe" qui consiste à créer une fonction qui a comme paramètre le texte à afficher : Variables & Functions 3 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV <HTML> <HEAD> <SCRIPT language="Javascript"> function Affiche(Texte) {alert(Texte);} </SCRIPT> </HEAD> <BODY> <A href="javascript:;" onselectstart="Affiche('NotSelect1');"> Texte1 </A> <A href="javascript:;" onselectstart="Affiche('NotSelect2');"> Texte2 </A> </BODY> </HTML> Ce qui donne ceci : [javascript:; Texte1] Variables & Functions 4 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV [javascript:; Texte2] Résultat: Aucune différence visuellement mais vous n'avez plus qu'une seule fonction qui peut vous afficher n'importe quel texte... Travailler sur des variables dans les fonctions Lorsque vous manipulerez des variables dans des fonctions, il vous arrivera de constater que la variable retrouve sa valeur d'origine dès que l'on sort de la fonction, malgré toutes les affectations faites au sein de celle-ci ... Cela est dû à la portée des variables, c'est-à-dire selon qu'elles ont été définies comme variables globales ou locales. Une variable déclarée implicitement dans la fonction (non précédée du motclé var) sera globale , c'est-à-dire accessible après exécution de la fonction Une variable déclarée explicitement (précédée du mot-clé var) sera locale , c'est-à-dire accessible uniquement dans la fonction, toute référence à cette variable hors de la fonction provoquera une erreur (variable inconnue)... Variables & Functions 5 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Le mot-clé this Lorsque vous faîtes appel à une fonction à partir d'un objet, par exemple un formulaire, le mot clé this fait référence à l'objet en cours et vous évite d'avoir à définir l'objet en tapant window.objet1.objet2... ainsi lorsque l'on passe l'objet en cours en paramètre d'une fonction, il suffit de taper nom_de_la_fonction(this) pour pouvoir manipuler cet objet à partir de la fonction. Pour manipuler les propriétés de l'objet il suffira de taper this.propriete (où propriete représente bien sûr le nom de la propriété). this définit la fonction dans une définition de fonction, le nouvel objet dans un constructeur , mais undefined lors des appels en mode strict, l'objet courant dans une méthode, etc. Dans une fonction fléchée this représente le contexte englobant. Définir des objets avec les fonctions Les navigateurs ont leurs propres objets avec leur propriétés respectives. Il Variables & Functions 6 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV est toutefois possible de créer ses propres objets avec les propriétés qu'on leur définit. Imaginons que l'on veuille par exemple créer un objet arbre avec ses propriétés : type taille age Il est possible de créer l'objet Arbre en créant une fonction dont le nom est Arbre et qui définit les propriétés de l'objet en cours grâce au mot-clé this, en passant en paramètre chacune des propriétés : function Arbre(Type, Taille, Age) {<br style="box-sizing: inherit;">this.Type = Type;<br style="box-sizing: inherit;"><br style="box-sizing: inherit;">this.Taille = Taille;<br style="box-sizing: inherit;"><br style="box-sizing: inherit;">this.Age = Age;<br style="box-sizing: inherit;"><br style="box-sizing: inherit;">} Grâce au mot-clé new, il va être possible de créer des instances de l'objet Arbre (c'est-à-dire des objets possédant les propriétés de l'objet Arbre) : Arbre1 = new Arbre("peuplier", 14, 20) On peut ainsi créer autant d'instances que l'on désire... Variables & Functions 7 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Il est de plus possible d'ajouter un objet existant en tant que propriété d'un autre objet. Imaginons que vous créiez un objet proprietaire : function Proprietaire(Nom, Prenom) {<br style="box-sizing: inherit;">this.Nom = Nom;<br style="box-sizing: inherit;">this.Prenom = Prenom;<br style="boxsizing: inherit;">} Définissons maintenant l'objet Arbre comme suit : function Arbre(Type, Taille, Age, Proprietaire) {<br style="box-sizing: inherit;">this.Type = Type;<br style="box-sizing: inherit;">this.Taille = Taille;<br style="box-sizing: inherit;">this.Age = Age;<br style="box-sizing: inherit;">this.Proprietaire = Proprietaire;<br style="box-sizing: inherit;">} Il est alors possible de trouver le nom du propriétaire d'un arbre : Arbre.Proprietaire.Nom Ainsi que de le modifier si jamais le propriétaire change : Arbre1.Proprietaire.Nom = 'Dupont'; Variables & Functions 8 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Arbre1.Proprietaire.Prenom = 'René'; Fonctions anonymes inline : Une fonction anonyme inline est une fonction non identifiée, sans nom, destinée à s’exécuter en inline c’est-à-dire au moment où la page Web se charge dans le navigateur. Pour l’appeler explicitement on l’affecte (son adresse-mémoire) à une variable, on l’appelle avec cette variable avec ou sans parenthèses. Les parenthèses après le mot « function » dans la définition reçoivent les arguments des parenthèses à la fin de la définition de la fonction. La syntaxe de base d’une fonction anonyme inline est : (function(){})(); // boîte d’arguments dehors. ou Variables & Functions 9 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV (function(){ } )(); // boîte d’arguments dehors. ou (function(){}()); // boîte d’arguments dedans. ou (function(){ } ()); // boîte d’arguments dedans. ou Variables & Functions 10 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV !function(){ }(); Exemple : <script type="text/javascript"> "use strict"; //Mode strict ! var x=25; // Cette forme (exécution immédiate) // (function() { console.log(x) } (x)); // IDENTIQUE à Cette forme // !function(x) { console.log(x) } (x); // IDENTIQUE aussi à Cette forme // +function(x) { console.log(x) } (x); </script> Variables & Functions 11 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Exécution : 25 25 25 this.html:8:7 this.html:15:7 this.html:22:7 Attention à votre code. Voyez ces divers comportements : <script type="text/javascript"> // Sans les parenthèses d'exécution à la fin, n'exécute pas. console.log((function() false})); {console.log("Dummy"); return console.log((function() true})); {console.log("Dummy"); return console.log(!function() false} ); {console.log("Dummy"); return console.log(!function() true} ); {console.log("Dummy"); return console.log(+function() false} ); {console.log("Dummy"); return console.log(+function() true} ); {console.log("Dummy"); return console.log(-function() {console.log("Dummy"); return Variables & Functions 12 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV false} ); console.log(-function() true} ); {console.log("Dummy"); return console.log(~function() false} ); {console.log("Dummy"); return console.log(~function() true} ); {console.log("Dummy"); return console.log(void false} ); function() {console.log("Dummy"); return console.log(void true} ); function() {console.log("Dummy"); return console.log(function() false} ); {console.log("Dummy"); return console.log(function() {console.log("Dummy"); return true} ); console.log(function() {return ""}()); // Avec les parenthèses à la fin, exécute. console.log((function() {console.log("Dummy"); return false}) () ); console.log((function() {console.log("Dummy"); return true}) () ); console.log(!function() {console.log("Dummy"); return false} Variables & Functions 13 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV () ); console.log(!function() {console.log("Dummy"); return true} () ); console.log(+function() {console.log("Dummy"); return false} () ); console.log(+function() {console.log("Dummy"); return true} () ); console.log(-function() {console.log("Dummy"); return false} () ); console.log(-function() {console.log("Dummy"); return true} () ); console.log(~function() {console.log("Dummy"); return false} () ); console.log(~function() {console.log("Dummy"); return true} () ); console.log(void false}() ); console.log(void true}()); function(){console.log("Dummy");return function() {console.log("Dummy"); return console.log(function() {console.log("Dummy"); return false} () ); console.log(function() () ); {console.log("Dummy"); return true} </script> Variables & Functions 14 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Exécution : ƒ () {console.log("Dummy"); return false} ƒ () {console.log("Dummy"); return true} false false false NaN NaN -1 // NaN avec "use strict"; -1 // NaN avec "use strict"; undefined undefined ƒ () {console.log("Dummy") ; return false} ƒ () {console.log("Dummy") ; return true} Dummy false Dummy true Variables & Functions 15 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu Dummy true Dummy false Dummy 0 Dummy 1 Dummy -0 Dummy -1 Dummy -1 Dummy -2 Dummy undefined Dummy undefined Dummy false Dummy true JavaScript Tome-IV I. Une fonction anonyme inline s'exécute automatiquement pendant le chargement de la page Web de la même façon que les codes non contenues dans un(e) [bloc de] fonction. <script type="text/javascript"> p="Math.PI"; Variables & Functions 16 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV // Définition fonction ordinaire. function f(p){ console.log("Ds function f()"+p) } onload=fl; // Définition fonction anonyme inline. fonloading=(function(){ // s'exécute au chargement. console.log("DURANT CHARGEMENT :\nDs Anonyme : " + p.substr(4,6)); f(", Depuis fonloading()"); f2(", Depuis fonloading()"); } )(p); p=" D U M M Y "; // Définition fonction ordinaire. function f2(p){ console.log("Ds function f2()"+p); Variables & Functions 17 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV } // Définition fonction ordinaire. function fl(){ console.log("================\nJUSTE APRES CHARGEMENT"); f("dans fl, Depuis onload"); } </script> Exécution dans console.log : DURANT CHARGEMENT : Ds Anonyme : .PI fonloading.html:12:4 Ds function f(), Depuis fonloading() fonloading.html:6:2 Ds function f2(), Depuis fonloading() fonloading.html:21:3 ================ JUSTE APRES CHARGEMENT fonloading.html:26:3 Ds function f()dans fl, Depuis onload Variables & Functions 18 / 145 fonloading.html:6:2 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV II. Expressions de fonctions (fonctions lambdas) : Fonction comme valeur affectée à une variable à la place d'une expression = (très utile avec les fonctions anonymes) : Une expression de fonction est toute déclaration de fonction ne commençant pas avec le mot-clé function. function [nom]([param] [, param] [..., param]) { instructions } Entre accolades = facultatif. III. Déclaration de fonction génératrice (function*) : Déclaration de fonction génératrice : Variables & Functions 19 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV function* nom ([param[, param[, ... param]]]) { instructions } IV. Expression de générateur function* : Déclaration de fonction génératrice : function* [nom]([param] [, param] [..., param]){ instructions } V. Expression de fonction fléchée (=>) : Arrow functions (“fat arrow” functions). Nouvelle syntaxe depuis ES6, mini fonctions anonymes, plus concises (courtes : pas de mot-clé function, return est implicite selon la fonction imbriVariables & Functions 20 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV quée utilisée, accolades =curly brackets= pas obligatoires si une seule instruction). Une « arrow function » est liée de façon lexicale à sa valeur. Une fonction fléchée n’a pas besoin des tokens suivants : function, return, parenthèses, accolades, et point-virgule « ; ». <script type="text/javascript"> "use strict"; var x = _ => new Date(); console.log(x()); // Date 2018-01-28T11:19:14.663Z console.log(x().valueOf()); // 1517138354664 console.log(x().toString());//Sun Jan 28 2018 12:19:14 GMT+0100 console.log(String(x())); // Sun Jan 28 2018 12:19:14 GMT+0100 console.log(x().toTimeString()); // 12:19:14 GMT+0100 console.log(x().toLocaleTimeString()); // 12:19:14 console.log(x().toDateString()); // Sun Jan 28 2018 console.log(x().toLocaleDateString()); // 28/01/2018 </script> Exécution avec YANDEX : Variables & Functions 21 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Thu Jan 11 2018 21:07:37 GMT+0100 (Paris, Madrid) Exécution avec FireFox : Date 2018-01-11T20:09:56.001Z __proto__: Object { … } Une fonction fléchée ne possède pas ses propres valeurs pour this, arguments, super, ou new.target. Une fonction fléchée retourne par défaut : 1 Pendant la déclaration ou la définition : l’adresse (pointeur) de l’expression qui est à droite de la flèche double ; 2 À l’invocation : l’exécution de l'expression [qui peut être complexe, dans une paire d’accolades] qui est à droite de la flèche double, ici la restitution du nombre E. <script type="text/javascript"> Variables & Functions 22 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV 'use strict'; console.log((_ => Math.E)());// 2.718281828459045 </script> Dans cet exemple, « _ => Math.E » retourne l’adresse de l’expression simple « Math.E », et les parenthèses indiquent qu’il faut exécuter le contenu à cette adresse (comme une fonction) càd calculer « Math.E » (le nombre E). Dans une fonction fléchée, le token « this » ne réfère pas cette fonction, mais le « this » de son contexte environnemental (scope parent = portée ou fonction englobante). Une fonction fléchée ne devrait donc pas être utilisée comme méthode (fonction-propriété) d’un objet et ne peut servir comme constructeur <script type="text/javascript"> 'use strict'; var ffl = _ => {}; // TypeError: ffl is not a constructor // Variables & Functions test.html:7:14 23 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV let fflI = new ffl(); </script> « this » référant window : <script type="text/javascript"> 'use strict'; var nb = Math.PI; var dObj = { nb: Math.E, b: _ => this, // Fct Fléchée ret window c: function() { return this; // Fct ord ret dObj } } Variables & Functions 24 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV let retO = dObj; var x; console.log(x=retO.b()) // b fléchée affiche son this (window) console.log(x.nb) // Affiche PI (window) console.log(retO.nb) // Affiche E (local à dObj) let retC = dObj.c(); // Appel direct de dObj.c console.log(retC) // this = aussi dObj console.log(retC.nb) // Affiche E </script> Exécution : Window file:///K:/DADET/PROGS/test.html test.html:18:3 3.141592653589793 Variables & Functions test.html:21:3 25 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV 2.718281828459045 test.html:22:3 Object { nb: 2.718281828459045, b: b(), c: c() } test.html:25:3 2.718281828459045 test.html:26:3 Après dépliement : Window dObj: {…} b: b() name: "b" __proto__: function () c: c() length: 0 name: "c" prototype: Object { … } __proto__: function () nb: 2.718281828459045 __proto__: Object { … } Variables & Functions 26 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV nb: 3.141592653589793 x: Window dObj: Object { nb: 2.718281828459045, b: b(), c: c() } nb: 3.141592653589793 x: Window file:///K:/DADET/PROGS/test.html [default properties] __proto__: WindowPrototype { … } [default properties] __proto__: WindowPrototype { … } test.html:18:3 3.141592653589793 test.html:21:3 2.718281828459045 test.html:22:3 {…} b: function b() c: function c() nb: 2.718281828459045 __proto__: Object { … } 2.718281828459045 Variables & Functions test.html:25:3 test.html:26:3 27 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV « this » référant la fonction englobante : <script type="text/javascript"> "use strict"; function dObj(){ this.v = 30; this.ol = { foo : _ => this , foa : _ => this.v , fob : _ => Math.PI } } let iObj = new dObj(); console.log(iObj.ol.foo()); console.log(iObj.ol.foa()); console.log(iObj.ol.fob()); </script> Variables & Functions 28 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Exécution : dObj {v: 30, ol: {…}} ol: {foo: ƒ, foa: ƒ, fob: ƒ} v: 30 __proto__: Object 30 3.141592653589793 La fonction fléchée n’a pas accès à un « arguments » propre, elle prend celui de son environnement englobant. <script> // "use strict"; var arguments = Math.PI; var arr = _ => arguments; console.log(arr(100)); Variables & Functions 29 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV </script> Exécution : 3.141592653589793 <script> // "use strict"; function englob() { // La fonction fléchée n'admet pas arguments var f = (i) => arguments; // arguments de englob return f(2); // Appel de la fct fléchée } console.log(englob("text",5,{},function(){})); </script> Variables & Functions 30 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Exécution : (4) ["text", 5, {…}, bol(Symbol.iterator): ƒ] ƒ, callee: ƒ, Sym- 0: "text" 1: 5 2: {} 3: ƒ () callee: ƒ englob() length: 4 Symbol(Symbol.iterator): ƒ values() __proto__: Object 4 text 5 {} __proto__: Object Variables & Functions 31 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV La fonction fléchée utilise « arguments » de son environnement englobant ou même en JS standard comme variable ordinaire (le mode strict n’autorise pas d’utiliser les mots-réservés [cfr arguments] comme nom de variable). On peut contourner cette restriction avec les paramètres du reste : <script> "use strict"; function englob() { // Arguments de la fonction fléchée var ffl = (...paramRest) => paramRest; return ffl(5,7); } var ret=englob("text",5,{},function(){}); console.log(ret); console.log(ret.length); console.log(ret[0]); console.log(ret[1]); console.log(ret[2]); </script> Variables & Functions 32 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Exécution : (2) [5, 7] 0: 5 1: 7 length: 2 __proto__: Array(0) 2 5 7 undefined Si la fonction fléchée ne renvoie pas automatiquement la valeur escomptée, forcez avec un return explicite. Si la fonction doit seulement créer et retourner un littéral d'objet, l’littéral d'objet à retourner doit être entouré de parenthèses pour ne pas le confondre avec un corps de fonction, ou alternativement retournez l’objet avec un return explicite : Variables & Functions 33 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Exemple 1 : On ne transmet rien en argument et l’littéral d'objet est créé par la fonction fléchée : <script type="text/javascript"> "use strict"; // object literal (notez les parenthèses) // return implicite. var f = () => ({ matr:1234 , nom:"texte" }); console.log(f); console.log(f()); console.log(f().matr); console.log(f().nom); </script> Exécution : function f() Variables & Functions test.html:7:3 34 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Object { matr: 1234, nom: "texte" } test.html:8:3 1234 test.html:9:3 texte test.html:10:3 Exemple 2 : On transmet des primitives en arguments et l’littéral d'objet est créé et retourné par la fonction fléchée : <script type="text/javascript"> "use strict"; // object literal (notez les parenthèses) // return implicite. var f = (x,y) => ({ matr:x , nom:y }); // 1er lot de Candidat : console.log(f(123 , "Diasolukov")); console.log(f(145 , "Kenakov").matr); console.log(f(167 , "Beliokovicz").nom); Variables & Functions 35 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV // 2e lot de Candidat : console.log(f(234 , "Benjiokovicz")); console.log(f(256 , "Lorenkov").matr); console.log(f(278 , "Bastokov").nom); </script> Exécution : Object { matr: 123, nom: "Diasolukov" } test.html:8:2 145 test.html:9:2 Beliokovicz test.html:10:2 Object { matr: 234, nom: "Benjiokovicz" } test.html:13:2 256 test.html:14:2 Bastokov test.html:15:2 Exemple 3 : Création et renvoi par la fonction fléchée d’un littéral d'objet non entouré de parenthèses ni d’accolades avec retour explicite : Variables & Functions 36 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV <script type="text/javascript"> "use strict"; // Vu comme bloc de fonction sans «return» // Ici retournera « undefined » par défaut // Création littéral d'objet const objF = obj => { key: obj.nom; }; console.log(objF({nom:"xyz"})); </script> Exécution : undefined Écrivez plutôt : Variables & Functions 37 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV <script type="text/javascript"> "use strict"; let objF = obj => { // Bloc de fonction return {alias: obj.nom}; //Retour Littéral d'objet }; console.log(objF({nom:"xyz"})); console.log(objF({nom:"xyz"}).alias); </script> Ou mieux <script type="text/javascript"> "use strict"; // Littéral d'objet entre parenthèses let objF = obj => ({ alias: obj.nom Variables & Functions 38 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV }); // Retour implicite de l’littéral d'objet console.log(objF({nom:"xyz"})); console.log(objF({nom:"xyz"}).alias); </script> Exécution pour les deux : Object { alias: "xyz" } test.html:8:3 xyz test.html:9:3 Une fonction fléchée n’est pas (ne peut être) un constructeur et ne peut donc pas avoir de descendants. <script type="text/javascript"> "use strict"; let foo = _ => Math.E Variables & Functions 39 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu console.log(foo); JavaScript Tome-IV // Pointeur sur foo(); console.log(foo()); // Retour de foo(); var iobj = new foo(); // Instanciation de foo() </script> Exécution : function foo() test.html:6:3 2.718281828459045 test.html:7:3 TypeError: foo is not a constructor test.html:8:14 Syntaxe des fonctions fléchées : N.B.: Pas de saut de ligne entre la liste des paramètres et la flèche d'une fonction fléchée (AVANT. la double flèche). Fonction fléchée à un seul paramètre : Variables & Functions 40 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV p => instructions; Exemple : <script type="text/javascript"> "use strict"; var f = txt => txt.split(" "); // return explicie console.log(f("Diasoluka Luyalu Nzoyifuanga")); </script> Exécution : Array [ "Diasoluka", "Luyalu", "Nzoyifuanga" ] […] 0: "Diasoluka" Variables & Functions 41 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV 1: "Luyalu" 2: "Nzoyifuanga" length: 3 __proto__: Array [] Fonctions fléchées à deux paramètres ou plus : La liste de paramètres formels est entourée de parenthèses : (p1, p2, ... pn) => expressions; Exemple : <script type="text/javascript"> "use strict"; // Avec Fonction fléchée Variables & Functions 42 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV var ajouter = (id, name) => ({ matr:"Matr="+id, nom:"Name="+name }); const ret=ajouter (5, "Kaleidoscope"); console.log(ret); // Avec Fonction classique var ajout = function (id, name) { return { matr: "Matr="+id, nom: "Name="+name }; }; const ret2=ajout(10, "Vladivostock"); console.log(ret2); </script> Exécution : Object { matr: "Matr=5", nom: "Name=Kaleidoscope" } Variables & Functions 43 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV test.html:8:3 Object { matr: "Matr=10", nom: "Name=Vladivostock" } test.html:18:3 Si plusieurs arguments ou aucun du tout, ou avec des paramètres du reste, ou avec des valeurs par défaut, ou un paramètre qui utilise une décomposition, entourez-les de parenthèses. Ci-dessous, la fonction fléchée « fct » a deux paramètres, séparés par une virgule et entourés d’une paire de parenthèses : « [a,b] = [v,w] » et « {x:c , y:d} = {x:a+b , y:a*b} », sous forme de « décomposition pour la liste des paramètres » : la variable « a » prend la valeur de v=3, et la variable « b » prend la valeur de w=5, et la propriété « c » prend la valeur « a+b » = 8, la propriété « d » prend la valeur « a*b » = 15, pour l’expression « a+b * c+d » retournée implicitement et qui vaut 58. Attention : « a+b * c+d » === « a + (b*c) + d ». Fonction fléchée Sans paramètres : Variables & Functions 44 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV La place que devait occuper les paramètres formels est symbolisée par des parenthèses vides « () » ou un trait de soulignement « _ » : () = > expressions; Exemple 1 : <script type="text/javascript"> "use strict"; // return implicite « undefined » // consolog.log affiche "Bougez !" // et retourne « undefined » var f = () => console.log("Bougez !"); f(); // Appel de la fonction fléchée Variables & Functions 45 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV // Valeur « undefined » retournée par // console.log dans la fonction f() console.log(f()); </script> Exécution : Bougez ! test.html:7:17 undefined test.html:14:3 Exemple 2 : <script type="text/javascript"> f = () => console.log("LN de 10 = "+Math.log(10)); console.log(f()); </script> Variables & Functions 46 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Exécution : LN de 10 = 2.302585092994046 undefined Syntaxe minimale complète : ()=>{} //fonction fléchée vide, renvoie undefined ou _=>{} //fonction fléchée vide, renvoie undefined Sa syntaxe détaillée : Variables & Functions 47 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV ([param] [, param]) => { expressions } Sa syntaxe minimaliste : param => expression param : nom d'un argument, paire de parenthèses () si pas d'arguments ou si au moins deux arguments. Si un seul argument, parenthèses pas obligatoires : Exemple de syntaxe minimaliste : <script type="text/javascript"> // Fonction classique function a() { return "typeof a = " + typeof a} console.log( a ); Variables & Functions 48 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV console.log( a() ); // Fonction fléchée var b = ( _ => "typeof b = " + typeof b); console.log( b ); console.log( b() ); </script> Exécution avec FireFox : function a() test.html:4:4 a() arguments: null caller: null length: 0 name: "a" prototype: Object { … } __proto__: function () Variables & Functions 49 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV typeof a = function test.html:5:4 function b() test.html:9:4 name: "b" __proto__: function () typeof b = function test.html:10:4 Exécution avec YANDEX : ƒ a() { return "typeof a = " + typeof a} test.html:4 typeof a = function test.html:5 _ => "typeof b = " + typeof b test.html:9 typeof b = function test.html:10 instructions ou expression Si plusieurs instructions, les encadrer par des accolades. Si expression unique, accolades pas obligatoires. expression est aussi la valeur de retour implicite de la fonction. Variables & Functions 50 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Exemple 1 : <script type="text/javascript"> "use strict"; var x = () => console.log("Haut"); var y = _ => console.log("Bas"); x(); y(); </script> Exécution : Haut Bas Exemple 2 : Variables & Functions 51 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV <script type="text/javascript"> "use strict"; var x = (p) => console.log(p); var y = (q) => console.log(q); x(10); y( ()=>25 ); </script> Exécution : 10 test.html:3:18 function () () length: 0 name: "" Variables & Functions 52 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV __proto__: () apply: function apply() arguments: null bind: function bind() call: function call() caller: null constructor: function Function() isGenerator: function isGenerator() length: 0 name: "" toSource: function toSource() toString: function toString() Symbol(Symbol.hasInstance): undefined __proto__: Object { … } Exemple 3 : <script type="text/javascript"> Variables & Functions 53 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV "use strict"; var v = x => "+Math.log(x); } { return "LN de "+x+" console.log(v(Math.exp(1))); // LN de E console.log(v(Math.E)); // LN de E </script> Exécution : LN de 2.7182818284590455 = 1 LN de 2.718281828459045 = 1 Exemple 4 : <script type="text/javascript"> "use strict"; var arf = (x,y,z) => { Variables & Functions 54 / 145 samedi, 3. mars 2018 (12:08 pm) = J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV return "1 GigaByte = "+ Math.pow(Math.pow(x,y),z)+" Bytes" } console.log(arf(2,10,3)); </script> Exécution : 1 GigaByte = 1073741824 Bytes Fonctions fléchées avec les Arrays : La fonction fléchée ne contient que la structure des enregistrements : <script type="text/javascript"> "use strict"; Variables & Functions 55 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV var fn = (id, name) => ({id:id, name:name}); console.log( fn (4, "Kyle") ); </script> Exécution : Object { id: 4, name: "Kyle" } {id: 4, name: "Kyle"} id: 4 name: "Kyle" __proto__: Object constructor: ƒ Object() hasOwnProperty: ƒ hasOwnProperty() isPrototypeOf: ƒ isPrototypeOf() propertyIsEnumerable: ƒ propertyIsEnumerable() toLocaleString: ƒ toLocaleString() toString: ƒ toString() valueOf: ƒ valueOf() Variables & Functions 56 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV __defineGetter__: ƒ __defineGetter__() __defineSetter__: ƒ __defineSetter__() __lookupGetter__: ƒ __lookupGetter__() __lookupSetter__: ƒ __lookupSetter__() get __proto__: ƒ __proto__() set __proto__: ƒ __proto__() ou, la fonction fléchée contient les données des enregistrements : <script type="text/javascript"> pers = [ { id:'Pet', Mat:150 }, { id:'Jean', Mat:2500 }, { id:'July', Mat:1000 } ]; // Pour chaque membre de pers (map) Variables & Functions 57 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV // cette Array pers est mise en argument // et retourne implicitementson mat. console.log(pers.map( pers => pers.id+" = "+pers.Mat)); </script> Exécution : Array [ "Pet = 150", "Jean = 2500", "July = 1000" ] test.html:12:3 1 (3) ["Pet = 150", "Jean = 2500", "July = 1000"] A 0:"Pet = 150" B 1:"Jean = 2500" C 2:"July = 1000" D length:3 E __proto__:Array(0) Variables & Functions 58 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Une variante plus complexe de ce qui précède : <script type="text/javascript"> "use strict"; var pers = [ { id:'Pet', Matr:150 }, { id:'Jean', Matr:250 }, { id:'July', Matr:100 } ]; // Pour chaque membre de pers (map) // cette Array pers est mise en argument // et retourne implicitementson Matr. console.log(pers.map( x => x.id+" = "+x.Matr)); console.log(">========<") Variables & Functions 59 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV var map = new Map(Object.entries(pers)); console.log(map); console.log("X========X") console.log(pers.map( x => new Map(Object.entries(x)))); console.log("<========>") var db = pers.map(x => x); console.log(db) console.log(db.map( x => new Map(Object.entries(x)))); console.log("====X====") db = pers.map(x => [x]); console.log(db) Variables & Functions 60 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV console.log(db.map( x => new Map(Object.entries(x)))); </script> Exécution dans la console de YANDEX : A (3) ["Pet = 150", "Jean = 250", "July = 100"] test.html:14 1 (3) ["Pet = 150", "Jean = 250", "July = 100"] A 0:"Pet = 150" B 1:"Jean = 250" C 2:"July = 100" D length:3 E __proto__:Array(0) >========< test.html:17 Map(3) {"0" => {…}, "1" => {…}, "2" => {…}} test.html:20 1 Map(3) {"0" => {…}, "1" => {…}, "2" => {…}} A size:(...) Variables & Functions 61 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu B __proto__:Map C [[Entries]]:Array(3) I 0:{"0" => Object} II 1:{"1" => Object} III 2:{"2" => Object} IV length:3 JavaScript Tome-IV X========X test.html:22 (3) [Map(2), Map(2), Map(2)] test.html:24 1 (3) [Map(2), Map(2), Map(2)] A 0:Map(2) {"id" => "Pet", "Matr" => 150} B 1:Map(2) {"id" => "Jean", "Matr" => 250} C 2:Map(2) {"id" => "July", "Matr" => 100} D length:3 E __proto__:Array(0) <========> test.html:27 (3) [{…}, {…}, {…}] test.html:30 1 (3) [{…}, {…}, {…}] A 0:{id: "Pet", Matr: 150} B 1:{id: "Jean", Matr: 250} Variables & Functions 62 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu C 2:{id: "July", Matr: 100} D length:3 E __proto__:Array(0) JavaScript Tome-IV (3) [Map(2), Map(2), Map(2)] test.html:31 1 0:Map(2) {"id" => "Pet", "Matr" => 150} 2 1:Map(2) {"id" => "Jean", "Matr" => 2500} 3 2:Map(2) {"id" => "July", "Matr" => 1000} 4 length:3 5 __proto__:Array(0) ====X==== test.html:34 (3) [Array(1), Array(1), Array(1)] test.html:37 1 (3) [Array(1), Array(1), Array(1)] A 0:[{…}] B 1:[{…}] C 2:[{…}] D length:3 E __proto__:Array(0) (3) [Array(1), Array(1), Array(1)] test.html:37 1 Array(1) Variables & Functions 63 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu A 0:{id: "Pet", Matr: 150} B length:1 C __proto__:Array(0) JavaScript Tome-IV 1 1:Array(1) A 0:{id: "Jean", Matr: 250} B length:1 C __proto__:Array(0) 1 2:Array(1) A 0:{id: "July", Matr: 100} B length:1 C __proto__:Array(0) 1 length:3 2 __proto__:Array(0) (3) [Map(1), Map(1), Map(1)] test.html:38 1 (3) [Map(1), Map(1), Map(1)] A 0:Map(1) {"0" => {…}} B 1:Map(1) {"0" => {…}} C 2:Map(1) {"0" => {…}} D length:3 Variables & Functions 64 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu E JavaScript Tome-IV __proto__:Array(0) 1 0:Map(1) A size:(...) B __proto__:Map C [[Entries]]:Array(1) I 0:{"0" => Object} a key:"0" b value:{id: "Pet", Matr: 150} I length:1 1 1:Map(1) A size:(...) B __proto__:Map C [[Entries]]:Array(1) I 0:{"0" => Object} a key:"0" b value:{id: "Jean", Matr: 2500} I length:1 1 2:Map(1) A size:(...) Variables & Functions 65 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu B __proto__:Map C [[Entries]]:Array(1) I JavaScript Tome-IV 0:{"0" => Object} a key:"0" b value:{id: "July", Matr: 1000} I length:1 1 length:3 2 __proto__:Array(0) En plus simple : <script type="text/javascript"> "use strict"; var obj = { Nom: "Pierre", Matr: 123 , Titre: "Bel Ami" , Prix: 100}; var map = new Map(Object.entries(obj)); console.log(map); Variables & Functions 66 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV </script> Exécution avec YANDEX : 1 Map(4) {"Nom" => "Pierre", "Matr" => 123, "Titre" => "Bel Ami", "Prix"=> 100} A size:(...) B __proto__:Map C [[Entries]]:Array(4) I 0:{"Nom" => "Pierre"} II 1:{"Matr" => 123} III 2:{"Titre" => "Bel Ami"} IV 3:{"Prix" => 100} V length:4 Exécution avec FIREFOX : Map { Nom → "Pierre", Matr → 123, Titre → "Bel Ami", Prix → 100 } test.html:6:3 Variables & Functions 67 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Map size: 4 <entries> 0: Nom → "Pierre" 1: Matr → 123 2: Titre → "Bel Ami" 3: Prix → 100 __proto__: Object { … } Visualisation du code de la fonction fléchée dans la console : Array [ "Pierre = 150", "Jean-Baptste = 2500", "Juliana = 1000" ] […] 0: "Pierre = 150" Variables & Functions 68 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV 1: "Jean-Baptste = 2500" 2: "Juliana = 1000" length: 3 __proto__: [] concat: function concat() constructor: function Array() copyWithin: function copyWithin() entries: function entries() every: function every() fill: function fill() filter: function filter() find: function find() findIndex: function findIndex() forEach: function forEach() includes: function includes() indexOf: function indexOf() join: function join() keys: function keys() lastIndexOf: function lastIndexOf() Variables & Functions 69 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV length: 0 map: function map() pop: function pop() push: function push() reduce: function reduce() reduceRight: function reduceRight() reverse: function reverse() shift: function shift() slice: function slice() some: function some() sort: function sort() splice: function splice() toLocaleString: function toLocaleString() toSource: function toSource() toString: function toString() unshift: function unshift() Symbol(Symbol.iterator): undefined Symbol(Symbol.unscopables): undefined __proto__: {…} Variables & Functions 70 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV __defineGetter__: function __defineGetter__() __defineSetter__: function __defineSetter__() __lookupGetter__: function __lookupGetter__() __lookupSetter__: function __lookupSetter__() constructor: function Object() hasOwnProperty: function hasOwnProperty() isPrototypeOf: function isPrototypeOf() propertyIsEnumerable: function propertyIsEnumerable() toLocaleString: function toLocaleString() toSource: function toSource() toString: function toString() unwatch: function unwatch() valueOf: function valueOf() watch: function watch() VI. Avec le constructeur Fonction (new Function) : Pas très commode. Variables & Functions 71 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV new Function( [arg1[, arg2[, ... argN]],] corpsFct ) Exemple : Quelle date après X jours ? <script type="text/javascript"> "use strict"; var dsXjrs = new Function('a, b', // ou var dsXjrs = new Function('a, b', 'return (a + ". *** Ds " + b + " jrs il sera : "\ +new Date(\ a.getFullYear(),a.getMonth(),a.getDate()+b))'); const j=dsXjrs(new Date(), 125); console.log(j); /* Fri Feb 16 2018 15:13:50 GMT+0100 (Afr. centrale Ouest). *** Ds 125 jrs il sera : Thu Jun 21 2018 00:00:00 GMT+0100 (Afr. centrale Ouest) */ dsXjrs.newpropr="NEWLY ADDED PROPERTY"; console.log(dsXjrs.newpropr); // NEWLY ADDED PROPERTY Variables & Functions 72 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV dsXjrs.prototype.newprotMethod=_=>Math.PI console.log(dsXjrs.prototype.newprotMethod()) // 3.141592653589793 console.log(Object.getOwnPropertyNames(dsXjrs)) // Array [ "newpropr", "prototype", "length", "name" ] console.log(Object.getOwnPropertyDescriptors(dsXjrs)) // Object { newpropr: {…}, prototype: {…}, length: {…}, name: {…} } console.log(Object.hasOwnProperty(dsXjrs)) // false console.log(Object.prototype) // Object { … } // __defineGetter__: function __defineGetter__() // __defineSetter__: function __defineSetter__() // __lookupGetter__: function __lookupGetter__() Variables & Functions 73 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV // __lookupSetter__: function __lookupSetter__() // constructor: function Object() // hasOwnProperty: function hasOwnProperty() // isPrototypeOf: function isPrototypeOf() // propertyIsEnumerable: function propertyIsEnumerable() // toLocaleString: function toLocaleString() // toSource: function toSource() // toString: function toString() // valueOf: function valueOf() </script> VI Fonction anonyme inline : Exécute au chargement du fichier et ordinairement une seule fois. Appelée « expression de fonction immédiatement invoquée » (Immediately Invokable Function Expression = IIFE). Les IIFE sont appelées dès la fin de leur déclaration. Les parenthèses terminales commandent d’ailleurs l’exécution immédiate de la fonction (function() { Variables & Functions 74 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV /* instructions */ })(); Si une fonction ordinaire passe son adresse à la variable de gauche lors de sa définition, une IIFE n’affecte pas son adresse à la variable. Il ne sert donc à rien d’écrire : var f = (function(){ console.log (this) })(); // TypeError: f is not a function // f(); Exécution : this n’est pas reconnu. Undefined test.html:4:22 Tout objet soit-il fonction (son adresse) peut être affecté à une variable. Variables & Functions 75 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Les fonctions appelées (avec parenthèses) retournent toujours la valeur de l’expression qui suit la directive return, par défaut (quand cette directive ne figure pas dans la fonction ou quand elle ne spécifie pas une valeur de retour) elles retournent undefined. Pendant la définition d’une fonction non inline (IIFE) ou quand une fonction est invoquée sans parenthèses en dehors de définition, elle retourne son adresse-mémoire (pointeur). Exemple 1 : <script type="text/javascript"> "use strict"; // Fonction inline, exécute var pi = (() => Math.PI)(); // Affiohe valeur retournée ci-haut console.log(pi); // Fonction à exécution différée Variables & Functions 76 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV var nep = () => Math.E; // Exécution de la fonction console.log( nep() ); </script> Exécution : 3.141592653589793 test.html:12 2.718281828459045 Exemple 2 : <script type="text/javascript"> "use strict"; // Il exécute directement et // retourne ici même une valeur. // On ne peut l'appeler de nulle part ailleurs Variables & Functions 77 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV var foa = (function(){ return("Ret in foa") })() // Il n'exécute pas directement et // retourne ici l'adrersse de son adresse var FOB = function(){ return("Ret in FOB") } console.log(foa); // Contenu retourné à foa console.log(FOB); // Contenu à l'adresse de FOB console.log(FOB()); // Exécute Contenu pointé // à l'adresse de FOB </script> Exécution : Ret in foa Variables & Functions 78 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV ƒ (){ return("Ret in FOB") } Ret in FOB Exemple 3 : <script type="text/javascript"> "use strict"; var dObj = function(){ this.v=45; console.log (this); return this; }; // Instanciation de dObj() Variables & Functions 79 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV var foo = new dObj(); // Pointeur sur dObj() cô fonction var fof = dObj; // Instanciation de foo() // TypeError: foo is not a constructor // Une instance ne peut être constructeur // var fop = new foo(); console.log(dObj); console.log(foo); // Pointeur sur constructeur // Pointeur sur l'instance console.log(foo.v); // Accès à propriété d'objet console.log(fof); // Pointeur sur fonction dObj console.log(fof.v); // undefined </script> Exécution : Variables & Functions 80 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Rendez-vous bien aux numéros des lignes. dObj {v: 45} test.html:6:5 function dObj() test.html:21:1 ƒ (){ this.v=45; console.log (this); return this; } dObj {v: 45} test.html:22:1 45 test.html:23:1 function dObj() test.html:24:1 ƒ (){ this.v=45; console.log (this); Variables & Functions 81 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV return this; } undefined test.html:25:1 Affectation d'une fonction : 1. Par fonction anonyme : Par affectation à une variable, de l’adresse de la fonction anonyme inline pendant sa définition. a. var v=(function(){})(); Définition et affectation d’une fonction anonyme non inline : b. var v=function(){}; 2. Par identification de fonction : idem que 1b. Variables & Functions 82 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV c. var v=function v(){}; Affectation de l’adresse (et appel) de la fonction ci-dessus (dans c). N.B.: Pas de parenthèses dans le nom de la fonction affectée : d. af=v ; af(); 3. Adresse de la fonction retournée par la fonction englobante. <script type="text/javascript"> function f1(){ // f3 = adresse de la fonction f2() en cours de définition var f3=function f2(){ console.log("Dans function f2()") } return f3; // retourne un pointeur sur f2() } // v prend l'adresse de la fonction f2() retournée par Variables & Functions 83 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV f1(). v=f1() // appel de la fonction f2() notez les parenthèses v() </script> Exécution dans console.log : Dans function f2() fcts.html:4 En fait, l'identifieur « f2 » ci-dessus ne sert absolument à rien. <script type="text/javascript"> f=function f2(){ console.log(new Date()); } f(); Variables & Functions 84 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV f2(); </script> Exécution : Date 2017-12-25T00:04:18.791Z id_rien.html:3:3 ReferenceError: f2 is not defined id_rien.html:7:2 Une autre fonction expression (type b. ci-dessus) : <script type="text/javascript"> var age = function(dn) { j=new Date(); return (j-dn)/1000/3600/24/365.2475 }; x=age(new Date("11 August 1953")); console.log(x+" ans."); Variables & Functions 85 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV </script> Exécution dans console.log : 64.36071000983478 ans. fvar_age.html:8 Le membre de gauche de l’affectation d’une fonction peut être une propriété d’objet, p. ex. « onclick » pour créer un événement : <body> <div><p>Cliquez ici</p></div> <p>Léger <strong>Gras</strong> Léger</p> </body> <script> //Accès au PREMIER paragraphe var pc = document.querySelector('p'); Variables & Functions 86 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV //Création de gestionnaire d'évènement "onclick" pc.onclick = function(){ this.innerHTML = 'Le click a été savoureux !'; this.style.color = "red"; this.style.borderStyle = "solid"; this.style.borderColor = "blue"; this.style.padding = "1em"; this.style.backgroundColor = "yellow"; this.style.width = "12em"; this.style.fontWeight = '900'; }; </script> </html> Exécution : Avant le click : Cliquez ici Variables & Functions 87 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Léger Gras Léger Après le click : Le click a été savoureux ! Léger Gras Léger Bien entendu, on peut écrire ceci : pc.onclick = function(){ corps de la fonction anonyme }; par exemple comme ceci : pc.onclick = fadr // Notez absence de parenthèses. fadr=function(){ corps de la fonction anonyme Variables & Functions 88 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV }; ou comme ceci : pc.onclick = fadr // Notez absence de parenthèses. function fadr (){ corps de la fonction anonyme }; Et au lieu de : pc.onclick = fadr // Notez absence de parenthèses. on peut écrire : pc. addEventListener('click',fadr,false); Variables & Functions 89 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Au lieu d’adresse de fonction comme paramètre, on peut directement utiliser une fonction anonyme s’exécutant sur place : pc.addEventListener('click',function(){ this.innerHTML = 'Le click a été savoureux !'; ... this.style.fontWeight = '900'; }); Passation de paramètres avec les différentes définitions de fonctions : Toute fonction peut passer/recevoir des paramètres d’un des 7 types de donnéeJS valides : n u m b e r (y compris le NaN), string, boolean (true ou false), object, function, null (vide = « absence de / aucune » valeur) et undefined. Mais JS affiche le « typeof null » comme étant un object (avec petit « o ») au lieu de null (erreur de JS). De plus « undefined » = aucune valeur affectée (néant), tandis que « null » = valeur affectée mais ne représentant rien. Attention donc à NaN, null et undefined. Variables & Functions 90 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Exemple : var vnull = null; // Affectation d’une valeur ne représentant rien. var vundefined; // Aucune valeur affectée même pas le null. Undefinde : Attention aux guillemets : var z; typeof z -> "undefined" z==undefined -> true z=="undefined" -> false (typeof z)==undefined -> false (typeof z)=="undefined" -> true undefined -> undefined undefined=="undefined" -> false nonexist -> Variables & Functions 91 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu Uncaught ReferenceError: fined at <anonymous>:1:1 JavaScript Tome-IV nonexist is not de- null : var z; typeof z -> "object" z==undefined -> true z=="undefined" -> false (typeof z)==undefined -> false (typeof z)=="undefined" -> false Contrairement aux langages C/C++, JS ne possède pas les types de données enum, structure...., et même les objets en JS ne sont pas vraiment comme les classes dans C/C++. 1. Définition classique de Fonction : Variables & Functions 92 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Avec le mot-clé function suivi du nom identifiant et de la liste de paramètres formels entre parenthèses max 255d (0xFF) paramètres/arguments, puis du bloc d’instruction de la fonction (corps de la fonction) entouré d’accolades (curly braces). function nom([param[, param[, ... param]]]) { instructions } Exemple : <script type="text/javascript"> // Déclaration/définition de fonction function fclassic(p1, p2, p3, p4, p5, p6, p7){ console.log(typeof p1+""+typeof p2+""+ typeof p3+""+typeof p4+""+typeof p5+ ""+typeof p6+""+typeof p7) } // Appel à la fonction Variables & Functions 93 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV fclassic(0/0,Math.PI,"Math.PI",(function(){ return 5==7})(),window,String) </script> Le paramètre p7 (type = undefined) n’a reçu aucun argument. Exécution : number number string boolean object function undefined N.B. : Ne confondez pas « types de données » (minuscules) et « objets standard » (Capitalisés) : Pour les instancier il faut utiliser l’opérateur new et appeler leur constructeur comme une fonction, p. ex new Date(). 2. Fonction anonyme_1 : Variables & Functions 94 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV <script type="text/javascript"> // Déclaration/définition de fonction fanonyme1=function(p1){ return p1.substr(4,6); } // Appel à la fonction console.log(fanonyme1("Math.PI")); </script> Exécution : .PI fano.html:9:2 Attention ici : a) fanonyme1=function(p1){...} :fanonyme prend l’adresse pointée par la fonction, soit-elle anonyme ou ordinaire. Variables & Functions 95 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV b) v=fanonyme1("Math.PI") :v prend la valeur retournée par la fonction anonyme dont fanonyme1 avait pris l’adresse. 3. Fonction anonyme_2 : Fonction anonyme inline affectée à fano, appel sans les parenthèses : <script type="text/javascript"> // Déclaration/définition de fonction fano=(function(){ console.log(4 + 6 + " | 4 + 6 = "+ 4 + 6); } )(); // Appel à la fonction fano(); </script> Variables & Functions 96 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Exécution : 10 | 4 + 6 = 46 typeof.html:4:3 4. Fonction anonyme_3 : Fonction anonyme inline affectée à v, appel avec les parenthèses : <script type="text/javascript"> var cpt=cptr=0; v=(function(p1,p2){ var x=0; var f3=function(){ console.log("Ds f2(): p1= ++cptr="+p1+ " , ++cpt="+ ++cpt+" , x="+x++ + " , p2="+p2.toLocaleString()) } Variables & Functions 97 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV return f3; })(++cptr,d()); for(k=0;k<2;k++) v("ignored1","ignored2"); function d(){return new Date()} </script> Exécution : Ds f2(): p1= ++cptr=1 , ++cpt=1 , x=0 , p2=21/12/2017 à 12:41:49 Ds f2(): p1= ++cptr=1 , ++cpt=2 , x=1 , p2=21/12/2017 à 12:41:49 5. En général : <script> function go(){ Variables & Functions 98 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV document.write(arguments.length+" Arguments :<br>") for(k=0,l=arguments.length;k<l;k++) document.write(arguments[k] + " | ") document.write("<br>") for(k in arguments) document.write(arguments[k] + " | ") } go("sérénité",new Date().toLocaleString(), Math.LN2.toFixed(2),2017) </script> Exécution : 4 Arguments : sérénité | 21/12/2017 à 01:02:59 | 0.69 | 2017 | sérénité | 21/12/2017 à 01:02:59 | 0.69 | 2017 | 6. Polymorphisme de fonction dans JavaScript : Variables & Functions 99 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Il n’existe pas de polymorphisme (overloading) de fonction dansJS vs C++ (voir p. 2/26 du Tome II de la série «À la découverte du langage C++» : Tout sur les Objets dans le Langage C, 1993, du même auteur). On gère cet état soi-même en testant le type de l’argument passé : <script <script type="text/javascript"> polymorphisme=function(p1,p2){ if(typeof arguments[1]=="undefined"){ console.log(p1+".p2==undefined") } if(typeof arguments[1]=="string"){ console.log(p1+". p2==string") } if(typeof arguments[1]=="number"){ console.log(p1+". p2==number") } if(typeof arguments[1]=="null"){ console.log(p1+". p2==null") } Variables & Functions 100 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV if(typeof arguments[1]=="function"){ console.log(p1+". p2==function") } if(typeof arguments[1]=="boolean"){ console.log(p1+". p2==boolean") } if(typeof arguments[1]=="object"){ console.log(p1+". p2==object") } } var a=[],b='diasoluka',c="1953"; polymorphisme(1,""); polymorphisme("1b","p2"); polymorphisme("1c",b); polymorphisme("1d",c); polymorphisme("1e",typeof Math); polymorphisme(2,5); polymorphisme("2b",eval("11"+"8")); Variables & Functions 101 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV polymorphisme(3,{}); polymorphisme("3b",new String()); polymorphisme("3c",Math); polymorphisme("3d",null); polymorphisme(4); polymorphisme("4b",undefined); polymorphisme(5, 4!=4); polymorphisme("5b",(function(){return true})()); polymorphisme(6,Boolean); polymorphisme("6d",Function); polymorphisme("6c",function(){}); </script> Exécution : 1. p2==string ,1b. p2==string ,1c. p2==string ,1d. p2==string ,1e. p2==string 2. p2==number ,2b. p2==number 3. p2==object , 3b. p2==object , 3c. p2==object , 3d. p2==object Variables & Functions 102 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV 4.p2==undefined , 4b.p2==undefined 5. p2==boolean , 5b. p2==boolean 6. p2==function , 6d. p2==function , 6c. p2==function 7. p2==string 7. Passation d’arguments «par valeur» et «par référence» en JavaScript : Les modifications apportées à un arguments passé par valeur (by value) dans la fonction appelée ne diffusent pas en dehors de la fonction. Les modifications apportées aux membres (attributs) d’un objet passé « par valeur » à une fonction appelée se reflètent en dehors de la fonction appelée. Le type object est donc un moyen de passer un argument par référence. <script> f=function(obj,j,m,a) { obj.x *= 3; // devient 33 dans l’objet Variables & Functions 103 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV obj.y += 10; // devient 18 dans l’objet obj.z -= 10; // devient 1943 dans l’objet j *= 3; // modifications locales m += 10; a -= 10; } var odummy = { x: 0, y: 1, z: 2 }; // Paramètres initiales. var j=j1=11, m=m1=8, a=a1=1953; console.log("Valeurs initiales : "+ "j1="+j1+" m1="+m1+" a1="+a1); // On les place dans un objet. odummy.x=j; odummy.y=m; odummy.z=a; Variables & Functions 104 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV // Appel de la fonction f() // Passation de l'objet cô argument (par référence) // Passation de j,m,a par valeur f(odummy,j1,m1,a1); // On récupères les valeurs modifiées j=odummy.x; m=odummy.y; a=odummy.z; console.log("Valeurs retournées : "+ "j="+j+" m="+m+" a="+a); console.log("Valeurs retournées : "+ "j1="+j1+" m1="+m1+" a1="+a1); </script> Exécution : Valeurs initiales : j1=11 m1=8 a1=1953 Valeurs retournées : j=33 m=18 a=1943 Valeurs retournées : j1=11 m1=8 a1=1953 Variables & Functions 105 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV On a vu que les fonctions sont des objets tout faits. Elles ont en effet des méthodes (par exemple les méthodes Apply, Call, Bind ) : I. La méthode « Apply() » appelle une fonction en lui passant une valeur this et des arguments sous forme d'un tableau (array) : [ p.ex. : Un littéral de tableau : function.apply (this , [el1', 'el2']) ou Un objet Array : function.apply (this , new Array('el1', 'el2')) ] ou sous forme d’un objet semblable à un tableau (tout objet possédant une propriété length et une propriété entière comprise entre [0...length[ ), par exemple un objet NodeList ou un quelconque objet comme {'length': 2, '0': 'faire', '1': 'rideau'}. Syntaxe = function.apply(thisArg, [argsArray]). <script type="text/javascript"> "use strict"; var numbers = [5, 9, -6, 3, 8]; var max = Math.max.apply(null, numbers); Variables & Functions 106 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV console.log(max); // 9 var min = Math.min.apply(null, numbers); console.log(min); // -6 </script> Le deuxième argument de « apply() » DOIT être un tableau ou similaire : <script type="text/javascript"> "use strict"; var numbers = [5, 9, 6, 3, 8]; var sqrt = Math.sqrt.apply(null, numbers[1]); // TypeError: second argument to Function.prototype.apply must be an array [FIREFOX] // Uncaught TypeError: CreateListFromArrayLike called on non-object [YANDEX] </script> II. La méthode « Bind() » permet de lier l’opérateur « this » à un environnement contextuel précis. Variables & Functions 107 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Bind à la définition de l’event handler : <button>Tirez un Candidat</button> <textarea id="txtar" readonly></textarea> <script type="text/javascript"> "use strict"; var candidat = { profil :[ {ID:"Martinez G.", matric:11}, {ID:"Robinson T", matric:55}, ///// {ID:"Melissa R", matric:00}, // SyntaxError: "0"-prefixed octal literals and octal escape sequences are deprecated; for octal literals use the "0o" prefix instead [FIREFOX] // Uncaught SyntaxError: Octal literals are not allowed in strict mode. [YANDEX] Variables & Functions 108 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV {ID:"Melissa R", matric:"00"}, {ID:"Bledina S", matric:33}, {ID:"Gregton B", matric:22} ], clickHandler:function (event) { // this est lié à candidat (bind dans appel). // Sans ce bind this réfère event-handler. let len = this.profil.length; var randomNum = (Math.random () * len | 0); document.getElementById("txtar").innerText = (this.profil[randomNum].ID + " #" + this.profil[randomNum].matric+ " ***Sur les "+len+" Prétendants."); } } document.getElementsByTagName("button")[0].addEventListen er( 'click', candidat.clickHandler.bind(candidat), Variables & Functions 109 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV false); </script> Exécution : Tirez un Candidat Robinson T #55 ***Sur les 5 Prétendants. Bind au niveau de l’initialisation du pointeur <script type="text/javascript"> "use strict"; // Candidats, variables globales var place=" GLOBAL =window"; var data = [ {ID:"Gregoire G", Matric:22}, {ID:"Bolivia G", Matric:33}, Variables & Functions 110 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV {ID:"Petgorje G", Matric:44} ] var user = { // Candidats, variables locales à objet user place:" LOCAL =user", data :[ // Propriété {ID:"Belinda U", Matric:55}, {ID:"Nelson U", Matric:66}, {ID:"Lesmor U", Matric:77}, {ID:"Belafonté U", Matric:77}, {ID:"Zirgont U", Matric:88}, {ID:"Zamith U", Matric:99} ], disp:function (event) { // Méthode // Le même this dépend du bind. const len=this.data.length; var aleat = (Math.random () * len | 0); window.cptr=0; Variables & Functions 111 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV console.log ("******RETENU* = "+ this.data[aleat].ID + " " + this.data[aleat].Matric); console.log("Parmi "+len+" prétendants ("+this.place+") :"); this.data.map(function(dummy){console.log(++cptr+"> "+dummy.ID+" "+dummy.Matric)}); } } // Pointeur sur méthode disp de user //// var dispVar = user.disp; // En mode "use strict"; // TypeError: this is undefined test.html:22:12 // disp file:///K:/DADET/PROGS/test.html:22:12 // <anonyme> file:///K:/DADET/PROGS/test.html:28:4 // Pointeur lié à global Variables & Functions 112 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV dispVar = user.disp.bind(window); dispVar (); // Candidats de window // Pointeur lié à user var dispVar = user.disp.bind(user); dispVar (); // Candidats de user </script> Exécution : ******RETENU* = Petgorje G 44 Parmi 3 prétendants ( GLOBAL =window) : 1> Gregoire G 22 2> Bolivia G 33 3> Petgorje G 44 ******RETENU* = Zirgont U 88 Parmi 6 prétendants ( LOCAL =user) : 1> Belinda U 55 Variables & Functions 113 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV 2> Nelson U 66 3> Lesmor U 77 4> Belafonté U 77 5> Zirgont U 88 6> Zamith U 99 En mode standard (non «use strict»;) JS est très tolérant et laisse passer l’instruction « var dispVar = user.disp; » qui était rejetée en mode «use strict;». this est du scope global car c’est là que le pointeur à la méthode disp() est défini. Ici window englobe l’objet user. <script type="text/javascript"> // "use strict"; // Candidats, variables globales var place=" GLOBAL =window"; var data = [ {ID:"Gregoire G", Matric:22}, Variables & Functions 114 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV {ID:"Bolivia G", Matric:33}, {ID:"Petgorje G", Matric:44} ] var user = { // Candidats, variables locales à objet user place:" LOCAL =user", data :[ // Propriété {ID:"Belinda U", Matric:55}, {ID:"Nelson U", Matric:66}, {ID:"Lesmor U", Matric:77}, {ID:"Belafonté U", Matric:77}, {ID:"Zirgont U", Matric:88}, {ID:"Zamith U", Matric:99} ], disp:function (event) { // Méthode // Le même this dépend du bind. const len=this.data.length; var aleat = (Math.random () * len | 0); Variables & Functions 115 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV window.cptr=0; console.log ("******RETENU* = "+ this.data[aleat].ID + " " + this.data[aleat].Matric); console.log("Parmi "+len+" prétendants ("+this.place+") :"); this.data.map(function(dummy){console.log(++cptr+"> "+dummy.ID+" "+dummy.Matric)}); } } // Pointeur sur méthode disp de user // En mode non "use strict"; var dispVar = user.disp; dispVar (); // Candidats de window // Pointeur liant this à global (window) dispVar = user.disp.bind(window); Variables & Functions 116 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV dispVar (); // Candidats de window //Pointeur liant this à user dispVar = user.disp.bind(user); dispVar (); // Candidats de user </script> Exécution : ******RETENU* = Gregoire G 22 Parmi 3 prétendants ( GLOBAL =window) : 1> Gregoire G 22 2> Bolivia G 33 3> Petgorje G 44 ******RETENU* = Bolivia G 33 Parmi 3 prétendants ( GLOBAL =window) : 1> Gregoire G 22 2> Bolivia G 33 Variables & Functions 117 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV 3> Petgorje G 44 ******RETENU* = Nelson U 66 Parmi 6 prétendants ( LOCAL =user) : 1> Belinda U 55 2> Nelson U 66 3> Lesmor U 77 4> Belafonté U 77 5> Zirgont U 88 6> Zamith U 99 III. La méthode « borrow » d’une fonction : Ci-dessous l’objet « producer » et l’objet « user » sont de même niveau, tous deux englobés dans l’environnement global, mais « producer » ne possède pas la méthode de « user » pour traiter (afficher) ses propres données. Au lieu de lier (BIND) la méthode « disp » de « user » à l’objet « producer » comme ci-dessus, « producer » peut emprunter (BORROW) cette méthode à partir de « user » , dans l’acception que « producer » n’a pas déjà cette méthode comme propriété propre, qui serait écrasée: Variables & Functions 118 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV La procédure est presque la même que ci-dessus (pour la partie de droite), et que quand on définit une nouvelle propriété pour un objet (pour la partie de gauche, mais au lieu d’une propriété ou une fonction indépendante, on affecte à la nouvelle propriété celle d’un autre objet) : <script type="text/javascript"> "use strict"; // Candidats, variables globales var producer = { place:" LOCAL =producer", data : [ {ID:"Gregoire G", Matric:22}, {ID:"Bolivia G", Matric:33}, {ID:"Petgorje G", Matric:44} ] } var user = { Variables & Functions 119 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV // Candidats, variables locales à objet user place:" LOCAL =user", data :[ // Propriété {ID:"Belinda U", Matric:55}, {ID:"Nelson U", Matric:66}, {ID:"Lesmor U", Matric:77}, {ID:"Belafonté U", Matric:77}, {ID:"Zirgont U", Matric:88}, {ID:"Zamith U", Matric:99} ], disp:function (event) { // Méthode // Le même this dépend du bind. const len=this.data.length; var aleat = (Math.random () * len | 0); window.cptr=0; console.log ("******RETENU* = "+ this.data[aleat].ID + " " + this.data[aleat].Matric); Variables & Functions 120 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV console.log("Parmi "+len+" prétendants ("+this.place+") :"); this.data.map(function(dummy){console.log(++cptr+"> "+dummy.ID+" "+dummy.Matric)}); } } // Pointeur liant this à user var dispVar = user.disp.bind(user); dispVar (); // Candidats de user // Nouvelle Méthode de producer (producer.disp) = // Pointeur sur la méthode user.disp() producer.disp = user.disp.bind(producer); producer.disp(); // Candidats de producer </script> Exécution : Variables & Functions 121 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV ******RETENU* = Zirgont U 88 Parmi 6 prétendants ( LOCAL =user) : 1> Belinda U 55 2> Nelson U 66 3> Lesmor U 77 4> Belafonté U 77 5> Zirgont U 88 6> Zamith U 99 ******RETENU* = Gregoire G 22 Parmi 3 prétendants ( LOCAL =producer) : 1> Gregoire G 22 2> Bolivia G 33 3> Petgorje G 44 Afficher la structure d’une fonction : Variables & Functions 122 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV <script type="text/javascript"> "use strict"; /*1*/ function fct(){ console.log("function fct()")}; /*2*/ var fct2=function(){ console.log("var fct2=function()")}; /*3*/ let fct3 = _ => console.log( "let fct3= _ =>"); fct3(); /*3b*/ _ => console.log("_ =>"); /*4*/ var fct4 = new Function( console.log("var fct4 = new Function")); /*5*/ var fct5 = (function(){ console.log("var fct5_1 = ((){})()") }) (console.log("var fct5_2")); Variables & Functions 123 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV /*6*/ !function(){ console.log("!function()")} // 2è appel (console.log("!function()_1")) // 1è appel (console.log("!function()_2")) // 3è appel (console.log("!function()_3")); // Erreur </script> Exécution : let fct3= _ => var fct4 = new Function var fct5_2 var fct5_1 = ((){})() !function()_1 !function() !function()_2 TypeError: (intermediate value)(...) is not a function Variables & Functions 124 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Dans la console : fct() length: 0 name: "fct" prototype: Object { … } __proto__: function () fct2() length: 0 name: "fct2" prototype: Object { … } __proto__: function () fct3() name: "fct3" __proto__: function () fct4 Variables & Functions 125 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV anonymous() arguments: null caller: null length: 0 name: "anonymous" prototype: Object { … } __proto__: function () fct5 undefined Console.log qui est un outils de développement (débogueur) n’affiche pas de la même façon que les autres instructions JS d’affichage. <script type="text/javascript"> function la_fct(p){ // Sans autre paramètre que le nom de la fonction, // donne son Type (expensible), affiché comme pointeur Variables & Functions 126 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV console.log(la_fct); // Avec d'autres paramètres que le nom de la fonction, // donne le Contenu = Code de la fonction. console.log(p+" + "+la_fct); } function appeleur(){ la_fct("***ARGUMENT***",2) } appeleur(); </script> Avec document.write : Le code source de toutes les fonctions est affiché. P.S.: nous avons ajouté un renvoi à la ligne avant ***ARGUMENT*** et simplifié les commentaires. Variables & Functions 127 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV function la_fct(p){ document.write(la_fct); // Type, dépliable document.write(p+" + "+la_fct); // Contenu = Code. } ***ARGUMENT*** + function la_fct(p){ document.write(la_fct); // Type, expansible document.write(p+" + "+la_fct); // Contenu = Code. } Avec console.log : function la_fct() ***ARGUMENT*** + function la_fct(p){ // Sans autre paramètre que le nom de la fonction, // donne son Type (expansible), affiché comme pointeur console.log(la_fct); Variables & Functions 128 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV // Avec d'autres paramètres que le nom de la fonction, // donne le Contenu = Code de la fonction. console.log(p+" + "+la_fct); } Exemple simple : <script type="text/javascript"> var Pomme = { couleur: "rouge", poids: 50, }; console.log(Pomme); console.log("Notre pomme : " + Pomme); </script> Exécution : Variables & Functions 129 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Object {couleur: "rouge", poids: 50} Notre pomme : [object Object] Avec le nom d’un objet seul comme paramètre, console.log affiche selon les navigateurs, soit seulement le nom de l’objet comme pointeur qu’on peut cliquer pour voir les détails de la structure de l’objet., soit directement ces détails. Avec d'autres paramètres que le nom de l’objet seul, console.log donne seulement la chaîne de caractères qui décrit l’élément (object Object pour indiquer que l’objet en cours est une instance de l’objet Object), car l’opérateur « + » agit comme opérateur de concaténation de chaînes de caractères dès que l’un des opérande est une chaîne. Or la conversion (transtypage = typecasting = type coercion = type conversion) d’un objet en chaîne de caractères fait automatiquement appel à la méthode toString() de l’objet en cours, et quand celui-ci n’en dispose pas, elle appelle la toString() native de l’objet « Object » (le parent de tous les objets que vous créez) qui n’affiche que ça. Si vous voulez autre chose que ce que le Object.toString() natif de l’objet Object (le parent de tous les autres objets) affiche, vous devez donc l’implémenter dans votre objet en cours pour prévaloir sur (override) celui (par défaut) de l’object Object. Variables & Functions 130 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Note : object avec « o » minuscule = substantif générique. Object avec « O » MAJUSCULE = Objet (structure de donnée) natif. Implémentation d’une méthode toString() pour l’objet Pomme. <script type="text/javascript"> Pomme = { couleur: "rouge", poids: 50, toString:function(){ v= "Couleur = "+this.couleur+" , poids = "+this.poids; return v; } } Variables & Functions 131 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV // Pointeur sur Pomme console.log(Pomme); // Appel implicite de Pomme.toString() console.log("Notre Pomme : " + Pomme); // Appel explicite de Pomme.toString() console.log("Notre Pomme : " + Pomme.toString()); </script> Exécution : Object { couleur: "rouge", poids: 50, toString: toString() } Notre Pomme : Couleur = rouge , poids = 50 Notre Pomme : Couleur = rouge , poids = 50 Notez que la Console permet d’afficher (dérouler) tous les niveaux de la structure de la fonction et de ses membres (attributs y compris les objets qui la constituent). Cliquons sur « Object { couleur: "rouge", poids: 50 } » dans la console pour avoir ceci : Variables & Functions 132 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV {…} couleur: "rouge" poids: 50 __proto__: Object { … } {…} symbolise un objet, puis vient son contenu (structure). Voyons comment une fonction ordinaire est représentée dans la console : <script type="text/javascript"> function notre_fct(p1,p2){ couleur= p1; var poids= p2; toString=function(){ v= "Coul = "+couleur+" , pds = "+poids return v; } } Variables & Functions 133 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV // Pointeur sur notre_fct console.log(notre_fct); console.log("==> notre_fct = "+notre_fct); </script> Exécution : function notre_fct() ==> notre_fct = function notre_fct(p1,p2){ couleur= p1; var poids= p2; toString=function(){ v= "Coul = "+couleur+" , pds = "+poids return v; } } Variables & Functions 134 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Dans la console, cliquons sur « function notre_fct() » et à l’intérieur, sur « __proto__ » (__proto__ = prototype du constructeur) notre_fct() arguments: null caller: null name: "notre_fct" __proto__: () apply: function apply() arguments: null bind: function bind() call: function call() caller: null constructor: function Function() isGenerator: function isGenerator() length: 0 name: "" toSource: function toSource() toString: function toString() Symbol(Symbol.hasInstance): undefined Variables & Functions 135 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV __proto__: Object { … } Fonctions imbriquées : Le code ci-dessous exécute l’addition de la fonction la plus interne. <script type="text/javascript"> function d_nais(jr){ return function (ms){ return function (an){ return an+ms+jr; } } } console.log(d_nais(30)(5)(10)) </script> Exécution : Variables & Functions 136 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV 45 Que s’est-il passé ? Voyons-le « images » étape par étape. Lisez bien les commentaires. <script type="text/javascript"> function d_nais(jr){ return function mois(ms){ return function annee(an){ return jr+"/"+ms+"/"+an; } } } console.log(d_nais(30)(12)(2017)) </script> Exécution : Variables & Functions 137 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV 30/12/2017 Un autre exemple : <script type="text/javascript"> function d_nais(an){ console.log("=> Dans d_nais()") return function mois(ms,hr){ console.log("=> Dans mois()") return function jour(jr,mn,sc){ console.log("=> Dans jour()") return ("=> "+new Date(an,ms1,jr,hr,mn,sc)).toString(); } } } console.log(d_nais) // Affiche d_nais(); console.log(d_nais()) // Exécute d_nais et affiche Variables & Functions 138 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV mois(); // Exécute jusqu'à mois et affiche jour() console.log(d_nais()()); // Exécute jusqu'à jour console.log(d_nais(1953)(11,15)(7,30,22)); </script> Exécution : function d_nais() => Dans d_nais() function mois() => Dans d_nais() => Dans mois() function jour() => Dans d_nais() => Dans mois() Variables & Functions 139 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV => Dans jour() => Sat Nov 07 1953 15:30:22 GMT+0100 Si c’est seulement pour obtenir l’affichage de la date, le plus important de ce script c’est la dernière instruction (on désactive les autres instructions dans un bloc de commentaire) : <script type="text/javascript"> function d_nais(an){ console.log("=> Dans d_nais()") return function mois(ms,hr){ console.log("=> Dans mois()") return function jour(jr,mn,sc){ console.log("=> Dans jour()") return ( "=> "+new Date(an,ms1,jr,hr,mn,sc)).toString(); } } } Variables & Functions 140 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV /* console.log(d_nais) // Affiche d_nais(); console.log(d_nais()) // Exécute d_nais et affiche mois(); console.log(d_nais()()); */ console.log(d_nais(1953)(11,15)(7,30,22)); </script> Ce qui est important dans le code ci-dessus, c’est le mode d’appel avec autant de parenthèses à partir de la fonction externe pour accéder à chaque niveau d’imbrication. Une autre façon d’obtenir exactement la mêm chose : <script type="text/javascript"> function d_nais(an){ console.log("=> Dans d_nais()") return function mois(ms,hr){ Variables & Functions 141 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV console.log("=> Dans mois()") return function jour(jr,mn,sc){ console.log("=> Dans jour()") return ("=> "+ new Date(an,ms-1,jr,hr,mn,sc)).toString(); } } } // retourne adresse de mois() v=d_nais(1953); // appelle mois() qui retourne adresse de jour() v=v(11,15) // appelle jour() qui retourne le résultat v=v(7,30,22) console.log(v) </script> Variables & Functions 142 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV Exécution : => Dans d_nais() => Dans mois() => Dans jour() => Sat Nov 07 1953 15:30:22 GMT+0100 On peut faire s’enchaîner des fonctions plus internes : <script type="text/javascript"> function d_nais(an){ console.log("=> Dans d_nais()") return function mois(ms,hr){ console.log("=> Dans mois()") return function jour(jr,mn,sc){ console.log("=> Dans jour()") return ("=> "+ Variables & Functions 143 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV new Date(an,ms-1,jr,hr,mn,sc)).toString(); } } } // retourne adresse de mois() v=d_nais(1953); // On peut enchaîner des fonctions plus internes // appelle mois() puis jour() qui retourne le résultat v=v(11,15)(7,30,22) // appelle jour() qui retourne le résultat // v=v(7,30,22) console.log(v) </script> Même Exécution : Variables & Functions 144 / 145 samedi, 3. mars 2018 (12:08 pm) J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-IV => Dans d_nais() => Dans mois() => Dans jour() => Sat Nov 07 1953 15:30:22 GMT+0100 Variables & Functions 145 / 145 samedi, 3. mars 2018 (12:08 pm)