De ES3 à ES5

Vue d'ensemble de

JavaScript avant ES6

CC-BY-NC-4.0 / avril 2020 / Loïc TRUCHOT

A faire pour 2021

  • + de "hard DOM"
    • createElement, createTextNode, appendChild, parentNode, closest
  • Bullet Two
  • Bullet Three

Un petit débat sur le fonctionnement du web

Client VS Server

IP -> TCP -> HTTP -> HTML -> JS

What The Fun JavaScript !!!

var a = typeof null === 'object',
  b = new Boolean(false), 
  c = NaN !== NaN, 
  d = [] + [] === '', 
  e = 0.1 + 0.2 !== 0.3, 
  f = x === 1 && x === 2 && x === 3; 
if (a && b && c && d && e && f) {
  console.log('WTF JavaScript !');
}

@voir github.com/denysdovhan/wtfjs, pour encore plus de « fun »

JavaScript le Malapris

  • Liberté et coercion
  • Progression fulgurante, « JavaScript fatigue »
  • Commencer des projets web sans formation
  • Utiliser librairies/frameworks sans les apprendre
  • Debugguer ou développer par c/c de stackoverflow
  • Langage interprété = punition en prod
  • Progr. fonctionnelle mal-aimée/incomprise
  • Principe de Postel domine web pour le meilleur... et pour le pire

 

malentendus => haine => cercle vicieux

Les dimensions de JavaScript

 

  • A l'origine:
    • Langage interprété destiné aux navigateurs web
    • rendre les pages plus dynamiques
    • déporter des calculs vers le client
  • Aujourd'hui:
    • environnement d'exécution (Node.js)
    • créer des applications webs, SPA (jQuery, React, Angular, Vue...)
    • ... mais aussi app mobiles (Ionic, React Native, Native Script), serveurs (Node.js + Express), logiciels (Electron), systèmes embarqués, OS, tout quoi !
  • Langages le plus utilisé au monde (github, stackoverflow, reddit, http://www.modulecounts.com/, etc.)... mais pas le préféré des devs !

Boîte à outil minimaliste

  • Bloc note
  • Node.JS
  • Invite de commande

Bases de la programmation

  • input =/=output
  • statements =/= expressions
  • LHS =/= RHS
  • des valeurs, dans des boîtes noires nommées
    • nom = "Mario"
  • valeurs brutes, expressions calculées en cascade
    • argent = 100 + (42 - 2)
  • Des opérations sur ces variables
    • phrase = nom + " possède " + argent + "€"
  • Des fonctions pour organiser ces opérations
  • Des fonctions pour organiser ces fonctions
  • Et ainsi de suite du plus simple au plus complexe

appliquées à JavaScript

Workshop

  • créer un fichier « test.js »
  • l'ouvrir avec le bloc-note
  • écrire un programme capable de calculer le nombre de m2 de mon appartement (dessiné au tableau)
    • var x = 3;
    • console.log(x);
    • node test.js

Back dans les bases

Le cycle infini du programmeur

  • Penser
  • Coder
  • Tester
  • Déboguer
  • Recommencer

Un peu d'histoire

  • 1995, Netscape veut un outil pour faire des calculs dans le HTML
  • Brendan Eich, un employé fan de Scheme, créé JavaScript en 10 jours  
  • Java à le vent en poupe, Netscape lui demande rendre ce nouveau langage conforme à la syntaxe Java (mais pas de POO).
  • IE créé JScript par retro-engieneering
  • Un guerre de 2 ans commence, jusqu'a l'arrivée d'ECMA

European Computer

  • 1997: début de la norme ECMA-262 avec ES1
  • 1998: ES2 - recommandations de conformité et d'implémentation uniquement

Manufacturers Association

  • 1999: ES3 - les bases du JavaScript moderne: syntaxe, regexp, erreurs, règles de coercion
  • 2000's: ES4 tente d'imposer POO dans JS: big fail

 

  • clarifie le comportement de JS, ajoute JSON, "use strict"
  • agrandie la boîte à outils: reduce, map, filter, find...
  • début de l'ES TC39 « new features process »
  • 2009: ES5

TC39

ES6

2015: grande réforme du langage JS pour sa version 6 aussi appelée ES2015.

Nouveautés: maps, sets, proxy, promise, iterators, generators, ..., =>, import, class, let-const...

ES7, 8, 8.5

  • Une version par an
  • Des apports mineurs:
    • clarifications de la v6
    • includes, async/await, finally, extra regex...

Parfois appelés ES2016, ES2017, ES2018...

ou encore 1.7.0, 1.8.0, 1.8.5

ou encore 7, 8, 9, 10

(juin 2019)

Un petit débat sur les paradigmes

Et JavaScript dans tout ça ?

ES3 à 5

Une syntaxe courte

Tout les mots clefs du langages tiennent sur une demi page.

/*

JAVASCRIPT FEW SYNTAX POETRY 
(by art4theSould)

Let this long package float,
Goto private class if short.
While protected with debugger case,
Continue volatile interface.
Instanceof super synchronized throw,
Extends final export throws.

Try import double enum?
- False, boolean, abstract function,
Implements typeof transient break!
Void static, default do,
Switch int native new.
Else, delete null public var
In return for const, true, char
…Finally catch byte.

*/

Une boîte à outils énorme

L'objet "window", implicite et omniprésent

 

Un petit tour chez Brico

Avant le prochain workshop

 

La variable

  • Ne commence pas par un chiffre
  • Ne comprends pas de caractères confus (ex: "-" ou " ")
  • N'est pas un mot clef réservé
  • Déclaration: var x;
  • Assignation: x = "value";
  • Les deux d'un coup: var x = "value";
  • peut tout contenir, même des fonctions
  • n'a pas de type forcé (son type change dynamiquement)
  • Rappel :
    • Scope = function
    • valeurs primitives (boolean, string, number) passées par copie
    • objets (arrays, objects, functions) passés par références

Choisir un nom

  • L'une des tâches les plus difficiles de l'informatique (avec l'invalidation de cache)
    • Trouver un nom vraiment descriptif
    • Donc pas trop vague
    • Et sans caractères spéciaux
    • Avec des mots bien séparés
    • Mais pas trop long
    • Mais au bon niveau d'abstraction
    • Mais avec consistance dans tout le programme
    • ...

Workshop

  • Qu'est ce qui est "variable" sur ce site ?
  • Nommez convenablement ces variables
  • Si on devait créer un univers virtuelle, avec nos lois physiques, qu'est-ce qui serait constant ?
<h1>Pizza YOLO</h1>
<h2>Hello Sonia !</h2>
<p>
    Today is friday: week-end is coming.<br />
    What about a delicious Pizza tonight, Sonia ?
</p>
<div>
    Try our classics :
    <ul>
        <li>Vegeteriana</li>
        <li>Il Diavolo</li>
        <li>Quattro Formagi</li>
    </ul>
    Or choose the daily chef choice:
    <strong>the Calzone</strong>
</div>
<p>
    <em>Pizza price: 10 € - See you soon Sonia.</em>
</p>

Les types

les valeurs, les références

Drôles de types

  • 3 types primitifs
    • boolean (true, false)
    • number (0, 1, -24, 12.7)
    • string ("test", 'test')
  • 3 type-valeurs vides
    • undefined
    • NaN
    • null
  • Un type composé
    • Object {}
    • et ses dérivés
      • Array []
      • Function () => ()
      • Regex /test/
      • etc.
      • vos combinaisons (collections ?)

Un language faiblement typé, aux types changeants

Pour ou contre un langage fortement typé ?

D'ailleurs c'est quoi au juste cette histoire de types ?

JavaScript VS Java

var chose = "string";
chose = 42; 
// pas d'erreur
var str: String = new String("string");
str = 42; 
// BOOM

Qui est le plus robuste ?

Qui est le plus léger ?

Une boîte de chocolat...

  • Opaque (non typée, ou plutôt typée dynamique)
    • Lorsqu'on vient de l'acheter
    • 3 ans plus tard
  • Transparente (typée)
    • Lorsqu'on vient de l'acheter
    • 3 ans plus tard
  • Une variable typée déclare son contenu autorisé, mais reste un partie un boîte noire
    • var x: UsignedInteger8bits = 10; 
  • Une fonction typée déclare ce qu'elle fait
  • Le trade-off
    • C'est beaucoup plus sécurisé, il n'y aura pas d'erreur, on sait ce qu'on fait en codant
    • Mais ça demande beaucoup plus de réflexion à chaque ligne de code, et de savoir où on va

Le type "number"

  • Pas de guillemet autour:
    • var x = 13 + 89.0;
  • Un ensemble allant de -Infinity à Infinity
    • avec les entiers (signed / unsigned integers)
  • Tous les nombres à virgule
    • avec les nombres à virgules (signed / unsigned floats)
  • Les opérations arithmétique de base
    • +, -, *, / 
  • Les opérations mathématique avancée
    • % (modulo), ++ (incrémentation), -- (décrémentation), - (changement de signe)

Workshop

  • Notre site montre des infos de films
  • Nous recevons leurs durées en minutes
    • Ex: 125 min, 190 min, 92 min
  • Nous souhaitons afficher cette durée en heure + minutes: 2h05,  3h00, 1h32

Jouer avec les nombres

Bonus: on peut aussi passer des durée en heures au programme, comme la chaîne "2h13" et si sait la convertir en minute

  • Utiliser vos connaissances sur les nombres pour faire un programme capable de faire ce calcul pour chaque film...
    • ...en suivant collectivement le "cycle du développeur"

Jouer avec les types

var empty = [undefined, null];
var primitives = ["Taille du rayon de la terre", 6371, true];
var objects = [{}, [], function() {}];
console.log(
  empty
    .concat(primitives)
    .concat(objects)
    .map(function(type) { return typeof type; })
    .join(",")
);
console.log("test".toUpperCase(), (6371).toFixed(2), true.toString());
  • [] sert à déclarer un nouvel Array (une liste), et ses élements
  • concat associe deux Array
  • map exécute une fonction sur chaque élément
  • join transforme l'Array en string
  • Commentez le code suivant:
// Décrire le code suivant
var prenom1 = 'Peach';
var prenom2 = prenom1;

// Quelle est la valeur de prenom2 ?

prenom1 = 'Mario';
// Quelle est la valeur de prenom2 ?

Types, valeurs et références...

// Décrire le code suivant
var personne1 = {
  prenom: 'Luigi',
  nom: 'Miyamoto'
};
var personne2 = personne1;

// Quelle est la valeur de personne2.prenom ?

personne1.prenom = 'Toad';
// Quelle est la valeur de personne2.prenom ?

...et maintenant

Workshop

  • ...

références

Bonus: ...

var game = "quizz";

function play() {
  var joueur1 = "Loïc";
  console.log(game, joueur1);

  if (joueur1 == "Loïc") {
    var score = 42;
    console.log(game, joueur1, score);
  }

  console.log(score);
}

play();

console.log(joueur1);

Commentez ce code

Portée des variables

  • le scope, c'est simplement « Où puis-je utiliser cette variable ? »
  • réponse différente pour chaque langage
  • en JS, le scope des variables est
    • la fonction où la var est déclarée, et ses descendantes (local)
      • OU
    • partout(global) - imaginer le scope global comme une méga-fonction
  • une fonction est comme mini-programme, avec ses propres variables + celles de ses parents (closure)
  • Ne JAMAIS oublier le mot clef « var » pour déclarer une nouvelle variable

ou « scope »

Les structures de contrôle

(Qu'on utilise vraiment)

Control flow = program's decisions

Conditions

  • if (cond) { ... }
  • if (cond) { ... } else { ... }
  • if (cond) { ... } else if (cond) { ... } else { ... }​
  • avec les opérateurs de comparaison
  • ===    égal
  • ==      vaut
  • !          contraire de
  • !==   n'est pas égal
  • !=       ne vaut pas
  • pour résoudre des équation booléenne
    • &&     "et" logique
    • ||          "ou inclusif" logique

 

  • >    Supérieur à
  • >=  Supérieur ou égal à
  • <    Inférieur à 
  • <=  Inférieur ou égal à

Vérifier et comparer

Autres conditions

  • switch case
    • pour tester plusieurs valeurs d'une seule variable
  • try catch
    • pour continuer malgré les erreurs
  • ternaire ( condition ? vrai : faux )
    • un if-else condensé

Workshop

Fizz Buzz !

Ouvrez votre éditeur et écrivez une fonction, qui prend en paramètre n'importe-quel nombre entier, et qui retourne :

  • "fizz" si c'est un multiple de 3
  • "buzz" si c'est un multiple de 5
  • "fizzbuzz" si c'est un multiple de 3 et 5
  • l'entier d'origine, s'il n'a pas de multiples associés

↓ alternative ↓

Bonus:

  • multiples de 7 = "hiss"
  • multiples de 11 = "howl
  • donc 1155 retourne "fizzbuzzhisshowl"

Workshop

Bonne nuit les petits

Ouvrez votre éditeur et écrivez une fonction, qui prend en paramètre un heure, et qui retourne :

  • "Bonjour" ou bien...
  • "Bonjour et bon appétit" si c'est le midi
  • "Bonsoir" après 16h
  • "Bonsoir et bon appétit" à 19h
  • "Bonne nuit les petits" de 21h à 6h
// log les chiffres de l'heure
console.log(new Date().getHours()); 

Bonus: randomiser les expressions, "salut", "coucou", "bon'ap", "Dors bien", "miam miam"...

Iterations

  • while
    • pour une boucle sans compteur
  • for
    • pour une boucle avec compteur
  • for of
    • pour une boucle sur les éléments d'un Array
    • TIPS: préférez forEach !
  • for in
    • pour une boucle sur les clés d'un Object

Workshop

 

  • écrire une fonction qui améliore ces burgers
  • elle prend en entrée un seul burger
  • elle retourne un burger amélioré ainsi:
    • si il y a  viande​ dedans, l'objet aura la propriété « veg:  false »
    • sinon, l'objet aura la propriété « veg: true »
var burgers = [
  { nom: "cheese", ingr: ["steak", "fromage"] },
  { nom: "tofu", ingr: ["tomate", "tofu", "fromage"] },
  { nom: "seitan", ingr: ["seitan", "salade"] }
];
// burgers[0].veg = true;

↓ alternative ↓

Burger queen

  • Bonus: différencier aussi les sandwitch "vegans".

Workshop

 

  • écrire une fonction donne le décompte total de kilomètres parcourus par le coureur, depuis qu'il possède cette montre
  • Bonus: écrire une fonction qui donne la moyenne de kilometre par ville (ex: moyenne("vientiane" , courses) retourne 4)
var courses= [
  { ville: "bruxelles", distances: [10, 13, 9, 23, 21, 5] },
  { ville: "paris", distances: [8, 18, 19, 11] },
  { ville: "vientiane", distances: [6, 3, 2, 5] },
];

La montre connectée

Un coureur assidu connecte sa montre en USB à son ordinateur, et obtient les donnée suivantes:

Live coding

  • Refacto: DRY et fonctionnel
  • Ajouter bootstrap
  • Délivrer le POC

Les structures de données

(Qu'on utilise vraiment)

La liste ou array

  • Déclaration:
  • peut tout contenir, même des fonctions
  • pointe vers référence en mémoire, pas copié,  partagé
    • var arr3 = arr1;
  • arr1.length pour connaitre sa taille
  • arr[0] pour le premier element
  • arr[1] pour le deuxième
  • quelques méthodes de base:
    • push, join, concat
var arr = [];
var arr1 = [true, "2", 3];
var arr2 = new Array(true, "2", 3);

La liste ou array

 

Workshop

  • Faites une petite listes de choses du même type (des légumes,  des chiffres, des planètes - ex: ["la courgette", "l'aubergine"])
  • Concaténez la avec une d'autres choses du même type (ex: ["la carotte", "la tomate"])
  • Filtrer avec un "for" pour exclure une partie de la liste (ex: exclure la tomate)

 

méthodes de listes

  • Bonus: Avec un "for", transformer en une liste de phrase annonçant le type: ["la courgette est un légume", "l'aubergine est un légume", "la carotte est un légume"]

L'objet

  • Déclaration:
var obj = {};
var obj1 = { key1: "val1", "key-2": "val2" };
var obj2 = new Object();
obj2.key3 = val;
  • peut tout contenir, même des fonctions (méthodes)
  • ces méthodes peuvent utiliser "this" pour référencer cet objet
  • pointe vers référence en mémoire, pas copié,  partagé
    • var obj3= obj1;
  • A des méthodes natives complexes

« this » dans une méthode d'objet

  • Exemple:
var chaton = {
  couleur: 'gris',
  cri: 'miaou',
  miauler() {
    console.log('le petit chat fait ' + this.cri);
  },
};
chaton.miauler();
  • Pratique pour utiliser une propriété dans une méthode
  • Vocabulaire de l'Orienté Objet
  • Attention, this ne correspond pas à la même chose hors d'un objet

Workshop session

this

  • Décrivez un animal, grâce à un objet. Il doit avoir
    • un nom (avec le déterminant, ex: "le crocodile")
    • un poids, une taille, une couleur
    • une méthode afficherDescription pour le décrire, grâce à des "this"

Bonus:

  • l'animal doit avoir une liste (array) de nourritures appréciées, ex: ["l'herbe", "les feuilles", "les fruits"]
  • Une méthode affiche ce qu'il aime. ex: "Le poney apprécie l'herbe, les feuilles et les fruits".
  • Envoyer le code de cet animal à l'enseignant

Stuctures courantes

  • la « collection »: un array d'objects tous formatés de la même manière
  • le « tuple » : un array limité en taille, aux types qui se répètent dans le même ordre
var people = [
  { nom: "Loïc", age: 34 },
  { nom: "Sabrina", age: 41 },
  { nom: "Swann", age: 22 }
];
var people1 = ["Loïc", 34];
var people2 = ["Sabrina", 41];
var people3 = ["Swann", 22];

Workshop

  • Dans le HTML, créez
    • un header avec le mot "Bonjour"
    • un input texte pour entrer un nom, avec l'id "nom"
    • un bouton "saluer", avec l'id "btn"
  • document.getElementById("nom").value donne la valeur de l'input
  • addEventListener permet d’exécuter une fonction au clic sur un élément HTML, comme suit :

intro à window

  • Arrangez vous pour que le nom change dans le header au click "Bonjour *nom* !".
var bouton = document.getElementById("btn");
bouton.addEventListener("click", function () {
  console.log("Quelqu'un a cliqué !");
});
element.innerHTML = "Bonjour " + nom;

Workshop

tous ensemble

  • Pour créer une div avec une bordure à gauche a partir de Javascript :
var div = document.createElement('div');
div.innerText = 'Bonjour.';
div.style.borderLeft = '1px solid black';
document.body.appendChild(div);
  • Récupérer la liste des animaux
  • Tester l'usage de console.table(animaux);
  • En itérant sur la liste, écrivez la description de chaque animal dans un paragraphe "p", avec une bordure basse grise pointillée de 2 px;

 

Bonus : ajouter le style backgroundColor: "lightgrey" à une div sur deux

Workshop

  • Créer trois array contenant chacun 8 mots: noms, verbes, ajds

  • Piocher au hasard dans chaque array un des mots

  • Assembler ces 3 mots ensemble

  • Répéter 3x le processus pour obtenir quelque chose comme:

    le chat est  gentil

    l'arbre est resplendissant

    le navire est rouge

  • Le haiku généré est affiché dans la page web

     

Bonus : féminins ?
pluriels ?

haiku generator

var haiku = "<ul>";
haiku += "<li>le chat est gentil</li>"
haiku += "</ul>"
document.body.innerHTML = haiku;

functions...

at least...

2 choses suffisent à l'informatique

  • La data (donnée):
    • une information à propos d'un fait, d'un événement, d'un phénomène, d'une chose
  • La fonction:
    • un calcul ou une action à faire avec les data, ou pour pour produire des data, ou les deux
  • Exemple de data -> fonction -> data
    • allumer un ordinateur
    • appuyer sur les touches d'une calculatrice
    • envoyer un formulaire
    • faire bouger un personnage dans un univers virtuel
  • Une fonction est elle même une forme de data: une série de règles de transformation 

Pourquoi écrire des fonctions ?

  • DRY
  • Mais pas que
  • découpage horizontal (modules)
    • ajouter, multiplier, soustraire, diviser
  • découpage vertical (abstractions)
    • calculer une série d'opérations différentes
  • imperatif (structures de contrôle = comment ?)
  • VS  déclaratif (fonctions = quoi ?)
  • √4  ?              √16 ??               54289 ???

Masquer les détails

 

  • Une fonction sert a encapsuler un petit programme, réutilisable dans un grand programme
  • Si cette fonction est totalement indépendante du reste, on pourra la réutiliser dans plusieurs programmes (fonction pure)
  • Sinon, on dit que la fonction à des effets de bord (side-effects)
  • La fonction cache une procédure complexe en une seule abstraction
  • Donc il faut très bien la nommer, sous peine d'erreurs !

We control complexity by building abstractions that hide details when appropriate.

S.I.C.P.

// OOOOOOPS
function ajouter(a, b) {
  return a - b;
}

Quizz "pure" ou "impure" ?

  • Une fonction qui modifie une variable du scope global ?
  • Une fonction qui modifie un objet qui lui est passé en paramètre ?
  • Une fonction qui fait une requête AJAX ?
  • Une fonction qui modifie le document HTML ?
  • Une fonction qui allume ou éteint la lumière ?
  • Une fonction qui ne retourne rien ? *
  • Une fonction qui n'a pas d'argument ? *
  • Une fonction qui utilise window.alert();
  • Une fonction qui sert à quelque chose dans le monde réel ?

Workshop

  • Ecrire des fonctions pures:
    • isOdd, isEven
    • getPlural, getEuro
    • toDiv, toList
    • en inventer une et la partager

La petite usine

function taillerCrayon(crayonNonTaille) {
  var crayonTaille = crayonNonTaille + "mine";
  return crayonTaille;
}

Déclaration vs Execution

Pour l'instant, il ne s'est rien passé dans le progamme.

Mais maintenant, on l'éxecute...

function ajouter(a, b) {
  return a + b;
}
  • déclaration d'une fonction nommée "ajouter"
  • deux arguments (inputs) "a" et "b", des nombres
  • un unique "retour" possible (output), un nombre
console.log(ajouter(3, 8)); // log 11
console.log(ajouter(5, 5)); // log 10
var nb = ajouter(2, 2); 
console.log(nb); // log 4
ajouter(2, 7); // ?
console.log(ajouter(3, ajouter(2, 1))); // ?

workshop

premier entretien d'embauche

  • coder une calculatrice simplifiée
  • il y a 4 fonctions pour faire ces opérations : +, - , *,  /
  • 2 inputs de type number, dans lesquels on écrit les chiffres
  • un bouton pour chaque opération
  • un input disabled qui présente le résultat quand on clic sur une opération

Bonus:  gérer les cas d'erreur (dont la division par 0) + arrondissez le résultat à 2 chiffres après la virgule + ajouter  l'opération puissance/exposant

alternative...

workshop

give me some $$$

  • créer 2 inputs dans le HTML
    • input n°1 qui est suivit du mot "USD"
    • un saut de ligne
    • input n°2, disabled, qui est suivit du mot "EUR"
  • lorsqu'on écrit un nombre dans l'input 1, le contenu de l'input 2 change tout seul: il converti en EUROS les DOLLARS

Bonus:  Ajouter des champs select pour choisir les devises, comme sur le conversions google

Bonus 2:  Ajouter 2 devises au choix

Arguments et signatures

function mettreAuPluriel (mot) {
  return mot + "s";
}
function mettreAuPluriel (str) {
  return str + "s";
}

Y a t-il une différence entre ces deux fonctions ?

Que faire s'il y a trop d'arguments ?

function mettreAuPluriel (mot, nombre, alt, force, admin, en) {
    // ...
}

Arguments et signatures

Quelle est la signature de cette fonction ?

function mettreAuPluriel (mot, nombre) {
  if (nombre > 1) {
    return mot + "s";
  } else {
    return mot;
  }
}
  • Pas de façon officielle d'écrire la signature en JS
  • Les arguments sont optionnels et illimités
  • "return" est optionnel, mais toutes les fonctions retourne qqch (undefined si pas de "return")
  • Le nom des arguments doit être bien choisi pour la lisibilité, mais ils sont interchangeables et invisibles lors de l'exécution
  • Attention aux shadowed names et au mots clés réservés
  • Attention au nombre d'arguments: 5 max, sinon découper fonction

Citoyen de première classe

  • En JS, les fonctions sont des valeurs comme les autres
// verifierMdp :: (string, string) -> void 
function verifierMdp(str, mdp) {
    alert(str === mdp? "ok" : "euh... en fait non.");
}
// ou...
var verifierMdp = function (str, mdp) {
    alert(str === mdp? "ok" : "euh... en fait non.");
}
// et...
var toto = verifierMdp;
toto("titi", "titi");

C'est la marque d'un language de programmation fonctionnelle

Attention, une fonction déclarée dans une var est souvent anonyme. On ne peut pas l'appeler avant sa déclaration dans le code

Callback

  • Une fonction de rappel (ou callback) est une fonction passée en argument à une autre, puis éxécutée dans celle-ci (souvent à la fin)
function premier (callback) {
  console.log("premier !");
  callback();
}
function deuxieme () {
  console.log("deuxieme");
}
premier(deuxieme);
premier(function() { alert("coucou"); });
  • Truc de fou, j'ai jamais fait ça ! ...euh... si en fait
button.addEventListener("click", function () { alert("coucou") });
[1,2].forEach(function (item) { alert(item) });
$.ajax("https://google.com").then(function (data) { alert(data) });

Workshop session

Callbacks

  • implémentez votre propre fonction for_each
  • Sa signature est : // for_each :: (Array, Function) -> void
  • forEach va exécuter une fonction pour chaque élément dans un tableau 

Bonus: implémenter votre propre map...

signature: // map :: (Array, Function) -> Array

Callstack

  • Un contexte d'exécution pour chaque fonction
  • Une pile, dont la taille monte et descend
  • LIFO: Last In First Out
  • Stack Overflow ? stack de 10 000 ?
  • L'instruction "throw": les erreurs sont nos amis
function a () { throw new Error() ;}
function b () { a(); }
function c () { b(); }

Live coding

A la découverte de la notion de récursion

ou comment itérer sans boucle itération ?

 

Méthodes avancées d'Array

  • Array.forEach(function...) pour itérer
  • Array.map(function...) pour transformer
  • Array.filter(function...) pour filtrer
  • Array.reduce(function...) pour "réduire"

L'usage des lambdas/callbacks est à la racine de toute programmation fonctionnelle avancée

Richard Waters developed a program that automatically analyzes traditional Fortran programs, viewing them in terms of maps, filters, and accumulations. He found that fully 90% of the code in the Fortran Scientific Subroutine Package fits neatly into this paradigm.

— SICP 1979

Méthodes avancées d'Array

var list = [
    { nom: "Françoise Albaret", age: 38},
    { nom: "Marcel Proust", age: 18 },
    { nom: "Charles Swann", age: 41 },
    { nom: "Albertine Simonet", age: 15 }
];
var ul = "<ul>";
list.filter(function (personne) {
    return personne.age > 21;
}).map(function (personne) {
    return `<li>${personne.nom} (${personne.age} ans)</li>`;
}).forEach(function (li) {
    ul += li;
})
ul += "</ul>";
document.body.innerHTML = ul;

Crazy chain

Décrire ce que produit ce code...

Workshop

réactions en chaîne

  • Charger JQuery
<script
  src="https://code.jquery.com/jquery-3.5.1.min.js"
  integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
  crossorigin="anonymous"></script>
  • Faire une requête AJAX
$.ajax("https://randomuser.me/api/?results=50").then(function (data) { 
    console.log(data.results);
});
  • Produire les prénoms dans le HTML
  • A côté du prénom il y a l'âge et le sexe
    • toto (H - 59 ans)
  • Ne pas garder les moins de 21 ans
  • Ne pas garder les habitants de Chine

Bonus:  Les personnes nées au mois d'octobre ont une petite icône de cadeau cliquable à côté de leur nom

Bonus 2:  Il ne peut pas y avoir 2 personnes avec le même email

L'objet « window »

Workshop

Ecrivez du JS, sauvez, rechargez le navigateur (console ouverte) :

  • utilisez window.console.log, window.console.error
  • utilisez window.alert, window.prompt, window.confirm

window, le couteau suisse

  • quelle est la valeur de "test" à la fin de ce script ?
  • Demandez de saisir un mot de passe (via  prompt).
    Si la personne écrit le mot de passe t0t0t1t1, alors il est prévenu qu'il est autorisé à utiliser le site.
  • Supprimez "window." devant chaque fonction (ex: console.log("test"); Que se passe-t-il ?
var test = window.prompt("blabla");

Workshop

Ecrivez du JS, sauvez, rechargez le navigateur (console ouverte) :

  • Ecrivez un programme capable de poser 3 questions de quizz d'affilée à un utilisateur, et de l'alerter si il a bon ou faux.

window, le couteau suisse

var test = window.document.getElementById("item");
  • va chercher l'élément html dont l'id est "item". (<div id="item"> par exemple), et le met dans la variable "test";
  •                                                              
  • écrit coucou en gras dans cette div.
  • Arranger vous pour donner le score sur 3 à la fin à même le HTML
test.innerHTML = "<strong>coucou</strong>";

Aucune règle

 

Rien n'est sacré en JavaScript, rien n'est jamais certain.

  • Mefiez vous du scope global
  • Mefiez vous des méthodes réécrites

DOM

Document Object Model

La représentation de votre HTML dans le JavaScript

// on connaît déjà...
var totoEl = document.getElementById("toto");
var bodyEl = document.body;
totoEl.innerHTML = "<span>coucou</span>";
bodyEl.addEventListener("mouseover", function () {});
// il y a des variations plus avancées:
var titiEl = document.getElementsByClassName("titi");
newDiv.innerText = "toto";
var newDiv = document.createElement("div");
body.appendChild(newDiv);
// reste "querySelector": le 1er el correspondant à ce descripteur CSS
var h1El = document.querySelector("h1");
var titiEl = document.querySelector(".titi");
var yoEl = document.querySelector("#yo");
// et querySelectorAll: array d'els correspondant à ce descripteur CSS
var listItems = document.querySelectorAll("li");

Et bien plus, avec JQuery, Angular, React...

Premier grand projet en JavaScript

Workshop

Bujo: les habitudes de la semaine

  • Le body de votre HTML contient uniquement: 
<div id="app"></div>
  • Trouver un manière adaptée de stocker toutes ces données dans le JavaScript
  • Ecrire un algorithme présentant proprement ces données dans le HTML (table ou flex ou ul ou carte)
  • Produire un CSS/SCSS joli/pratique pour cette page (tailles, polices, bordures, icônes...)
  • La totalité du code est produit par JavaScript

Workshop

Bujo: les habitudes de la semaine

Attention: cette approche n'est que "visuelle".

Pour pouvoir "sauver" l'état de votre bujo, il faudra VRAIMENT modifier la valeur "true/false" dans votre structure de donnée... et seulement après redessiner le "bujo" en fonction de cette structure...

  • Pour faire une belle boulette  (au sens premier) en HTML, copier coller ce caratère:         •
  • Rendre toutes les boulettes "cliquable"
  • Au clic sur une case contenant une boulette, elle disparaît
  • Au clic sur un espace "vide", elle apparaît

Workshop

Bujo: la todolist quotidienne

  • Pour chaque jour de la semaine, prévoir:
    • une todo list 
      • chose à faire
    • une event list
      • ce qui arrivera tout seul
      • ex: un annif, un salaire
  • Chaque "todo" est précédé d'une checkbox, cochée ou non
  • Cliquer sur une checkbox déjà cochée reporte l'évenement: la checkbox devient une icone de "report"
  • Bonus: Ici aussi, les donnée check/non-check/reporté viennent d'une seule structure de donnée vivante
  • Bonus 2: Toutes vos données tiennent d'ailleurs dans un seul mega-object

Workshop

Bujo: aller plus loin

  • Les todo-listes contiennent automatiquement les "hobby" qui ont été cochés ce jours, en lecture uniquement
  • cliquer sur un jour de la semaine permet d'en éditer la todolist
  • les cartouches d'habitudes et les jour de la semaines sont présents jusqu'au 31/12/2020 (avec le "range" de chaque semaine en titre des cartouches
  • Mettre votre oeuvre en ligne à l'aide du formateur

localStorage

  • localStorage est un outil JS front-end disponible dans window (aka le scope global)
  • il permet de mémorisée des données clientes, d'une session à l'autre
  • il s'efface si utilisateur efface sont historique et ses données de navigation
  • il ne marche pas entre navigateur, mais bien sur un seul
window.localStorage.setItem("prenom", "Marcel");

Sauver / Enregistrer

Retrouver / Charger

var prenom = localStorage.getItem("prenom");
if (prenom) {
    console.log("bonjour " + prenom);
}

Workshop

  • On demande à l'user sa couleur préférée (en anglais)
  • Cette couleur apparaît comme background du body
  • Mémoriser la couleur, et ne plus la redemander  si elle a déjà été choisie: setItem("a", "b") / getItem("a").

Youtube kids

// modifier le style du body
document.body.style.backgroundColor = "blue";

Bonus:

  • A la place d'un input, on a un select avec les noms de couleur en fr
  • faire trois boutons vert, jaune, rouge 
  • lorsqu'on click sur un bouton, ça change la couleur du background et la mémorise
  • A la place des couleurs, on a en fait des images de fond d'écran: princesse, dragon, ou lutin

JSON

  • Stringify (lire et transformer en chaîne)
  • Parse (lire et transformer en code)

JavaScript Object Notation

  • Un format d'échange parmi d'autres...

@see https://fr.wikipedia.org/wiki/JavaScript_Object_Notation

  • Mais super adapté à JavaScript ! Comme nos objets ou presque
  • Omniprésent dans l'univers de web: remplaçant de XML pour les API et pour les fichiers de conf (concurrence par YML et TOML)

Douglas Crockford

window.JSON.parse('{"toto": "titi"}');
window.JSON.stringify({toto: "titi"});

Warning: fonctions et structures circulaires/récursives interdites

Workshop

  • Bullet journal sauvegardable ? (state)
  • Tamagochi sauvegardable ? (états vitaux ?)
  • Louve solitaire sauvegardable ? (inventaire ?)

localStorage + JSON

  • installer parcel et jquery via NPM
  • ecrire un JSON décrivant les caractéristiques de votre PC (HDD, RAM, lecteur cd, processeur, nb de coeur, petit-nom-secret)
  • Afficher ça joliment dans le HTML grâce à une requête ajax

Bonus:

RegExp

  • Une regexp est un object !
  • Les expressions régulières sont un langage dans le langage
  • Cryptique, esotérique, très dur à relire, à éviter si possible
  • Utiles pour trouver des patterns dans une string
  • Liées au méthodes de strings (match, test, search, split, replace...)
  • Délaration:
    • littérale: /toto/g
    • constructeur: new RegExp("toto", "g");
var r = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;

if (!r.test(ipt.value)) {
  console.error("email incorrect")
} else {
  $.post("http://api.toto.com/user/new", { email: ipt.value });
}

La bête noire des devs

Workshop

  • Demander à l'utilisateur son nom et sa date de naissance
  • Tant que le format n'est pas "jj-mm-yyyy" afficher une erreur en rouge sous le champ

 

cherchez l'erreur

Bonus:

  • vérifier aussi que le nom est un nombre de lettre indéterminé sans chiffre ni caractère autres que " " et "-"
  • Lui demander son tel mobile avec l'indicatif de pays et vérifier qu'il correspond bien à:
    • +32 4XX XX XX XX (espaces facultatifs)
    • ou
    • +33 6X XX XX XX (idem)
    • +33 7X XX XX XX (idem)

Date

+ setTimeout + setInterval

// setTimeout::(function, number)->id
setTimeout(function () {
  alert("28 secondes plus tards..")
}, 28000);
  • Gestion du temps difficile en JS, librairie souvent nécessaire:
    • moment.js, date-fns, luxon.js

setTimeout: le delai

// setInterval::(function, number)->id
var intId = setInterval(function () {
  alert("Toutes les secondes");
}, 1000);
clearInverval(intId);

setInterval: la boucle

  • Une date est un object !
  • Nombreuses méthodes (confuses) pour faire du CRUD, formatter ou lire des sous-parties
  • Constructeur: new Date();
    • new Date(2018, 8, 22, 15, 0, 0)
    • new Date('2018-09-22T15:00:00')
  • Vrai format de calcul: le timestamp en milliseconds (since 1970)

Workshop

Loup garouuuuuuuu

Votre page présente un timer avant la prochaine pleine lune, qui change chaque seconde

Bonus: un design de lune en CSS représente l'état actuel de la lune

Bonus 2: lorsque la pleine lune arrive, la lune est pleine le fond du site devient noir, une musique etrange se lance et on entend le cri d'un loup.

Propagation

ou bubbling

  • La callback déclenchée lors d'un événement a un argument:
    • un objet complexe avec toutes les infos sur l'event en question
  • Un event est considéré comme appartenant à un élément parent
  • Un click sur le body sera fait dans un autre élément, et remonte jusqu'au body
document.body.addEventListener("click", function (event) {
  console.log(event.target); // le "sous-élement" cliqué
  console.log(event.currentTarget); // le body
});
  • Si cet élément a lui-même un event "click", le click sera "propagé jusqu'au body, et les deux events seront déclenché (trigger)
  • La bulle part de l'élément le plus profond... jusqu'a la window !
  • Sauf si event.stopPropagation()
  • ne pas confondre avec preventDefault()
document
  .querySelector("span")
  .addEventListener(function (e) {
    console.log(e);
  	e.stopPropagation(e);
});
window
  .addEventListener(function (e) {
    console.log(e);
  e.preventDefault();
});

Delegation

d'évènement

  • La délégation d'évènement consiste à écouter un évènement sur un element en contenant d'autres, puis cibler l'enfant concerné par cet évenement, le "target"
  • Utile pour:
    • ni pas itérer des objets de même type pour enregistrer le listener
    • ne pas surcharger la page de listener(< 10 000)
    • ne pas avoir à removeEventListener
    • ne pas avoir à rebinder des events sur des nouveaux éléments
document.body.addEventListener("click", function(e) {
  if (e.target.matches("button")) {
    console.log("un bouton a été cliqué", e.target);
    console.log("ceci est  le body:", e.currentTarget);
  }
});

e.target est toujours l'élement exact cliqué, et e.currentTarget est l'élément concerné par l'événement d'origine

Quelques inconnues...

  • "this" en javascript et l'émulation de classes
  • Prototype et Orienté Objet en ES5
  • Structures de contrôle bonus:
    • do while, switch case, etc.
  • Canvas et le monde de la 2D + WebGL
  • Attributes VS Properties
  • A lot of DOM props/methods: classList, setAttribute, parentNode...
  • événements spéciaux, propriétés étranges, constructeurs et type archi-spécialisés
  • Ne pas tout utiliser, mais utiliser bien ce qu'on a

à découvrir de votre côté

Appendice:  tu buuuugs !

  • RTFM / RTFE:
    • Erreur visible dans le code grâce au linter (ESLint)
    • Erreur dans ma console node/npm (terminal)
    • Erreur dans ma console browser (F12)
    • Erreur dans le network, dans l'inspecteur d'élément, dans le localstorage...
  • Element présent dans mon HTML, mais sans style (invisible, sans taille, blanc sur blanc, etc.)
  • Erreur de français/anglais, typos, etc
  • Erreur dans ma logique (ex: forEach sur un tableau vide)
  • Utilisez dans l'ordre: 
    • debugger;
    • console.log, console.table
    • stackoverflow / google
    • un canard en plastique
    • un ami
    • un formateur

Workhsop

Sécial buuuuuugs

vra nb = [8];;
var a =    "Les ${nb} petit" .
"poisons vont à" .
"à la rivière."

    var b = a.split("  ")
for(var a in B) {
    if (a == `petits`) {
console.log("plouf")
} else {
    console.log("PLOUF!!").then(get("lol.com"));}
}
  • Trouvez tous les bugs
  • Classez les par types et par gravité
  • Debugger ce code (utilisé ligne après ligne consoles et debuggers)

Ressources

  • Références incontournables:
    • https://developer.mozilla.org/fr/
    • https://www.w3schools.com/
  • MOOC vidéo de bonne qualité
  • Sites
    • https://javascript.info/
  • Livres
    • You Don't Know JS, Kyle Simpson
    • JavaScript: the good parts, Douglas Crockford
    • JavaScript: the definitive guide, David Flanagan
    • Eloquent JavaScript, by Marijn Haverbeke 

THANK'S EVERYONE
It's finally done ! See you soon

JavaScript 2020 - De ES3 à ES5

By Loïc TRUCHOT

JavaScript 2020 - De ES3 à ES5

Introduction à JavaScript, en français et sans compromis.

  • 1,275