Loïc TRUCHOT
JavaScript Fullstack Expert & Senior web developer
Vue d'ensemble de
JavaScript avant ES6
CC-BY-NC-4.0 / avril 2020 / Loïc TRUCHOT
Client VS Server
IP -> TCP -> HTTP -> HTML -> JS
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 »
malentendus => haine => cercle vicieux
nom = "Mario"
appliquées à JavaScript
Back dans les bases
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...
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)
Et JavaScript dans tout ça ?
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.
*/
L'objet "window", implicite et omniprésent
<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 valeurs, les références
Un language faiblement typé, aux types changeants
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 ?
var x = 13 + 89.0;
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
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());
// 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 ?
// 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 ?
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);
ou « scope »
(Qu'on utilise vraiment)
Control flow = program's decisions
if (cond) { ... }
if (cond) { ... } else { ... }
if (cond) { ... } else if (cond) { ... } else { ... }
Vérifier et comparer
Ouvrez votre éditeur et écrivez une fonction, qui prend en paramètre n'importe-quel nombre entier, et qui retourne :
↓ alternative ↓
Bonus:
Ouvrez votre éditeur et écrivez une fonction, qui prend en paramètre un heure, et qui retourne :
// log les chiffres de l'heure
console.log(new Date().getHours());
Bonus: randomiser les expressions, "salut", "coucou", "bon'ap", "Dors bien", "miam miam"...
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
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:
(Qu'on utilise vraiment)
var arr = [];
var arr1 = [true, "2", 3];
var arr2 = new Array(true, "2", 3);
méthodes de listes
var obj = {};
var obj1 = { key1: "val1", "key-2": "val2" };
var obj2 = new Object();
obj2.key3 = val;
var chaton = {
couleur: 'gris',
cri: 'miaou',
miauler() {
console.log('le petit chat fait ' + this.cri);
},
};
chaton.miauler();
Bonus:
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];
intro à window
var bouton = document.getElementById("btn");
bouton.addEventListener("click", function () {
console.log("Quelqu'un a cliqué !");
});
element.innerHTML = "Bonjour " + nom;
var div = document.createElement('div');
div.innerText = 'Bonjour.';
div.style.borderLeft = '1px solid black';
document.body.appendChild(div);
Bonus : ajouter le style backgroundColor: "lightgrey" à une div sur deux
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;
at least...
Pourquoi écrire des fonctions ?
We control complexity by building abstractions that hide details when appropriate.
S.I.C.P.
// OOOOOOPS
function ajouter(a, b) {
return a - b;
}
function taillerCrayon(crayonNonTaille) {
var crayonTaille = crayonNonTaille + "mine";
return crayonTaille;
}
Pour l'instant, il ne s'est rien passé dans le progamme.
Mais maintenant, on l'éxecute...
function ajouter(a, b) {
return a + b;
}
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))); // ?
premier entretien d'embauche
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...
give me some $$$
Bonus: Ajouter des champs select pour choisir les devises, comme sur le conversions google
Bonus 2: Ajouter 2 devises au choix
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) {
// ...
}
Quelle est la signature de cette fonction ?
function mettreAuPluriel (mot, nombre) {
if (nombre > 1) {
return mot + "s";
} else {
return mot;
}
}
// 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
function premier (callback) {
console.log("premier !");
callback();
}
function deuxieme () {
console.log("deuxieme");
}
premier(deuxieme);
premier(function() { alert("coucou"); });
button.addEventListener("click", function () { alert("coucou") });
[1,2].forEach(function (item) { alert(item) });
$.ajax("https://google.com").then(function (data) { alert(data) });
Bonus: implémenter votre propre map...
signature: // map :: (Array, Function) -> Array
function a () { throw new Error() ;}
function b () { a(); }
function c () { b(); }
A la découverte de la notion de récursion
ou comment itérer sans boucle itération ?
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
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...
réactions en chaîne
<script
src="https://code.jquery.com/jquery-3.5.1.min.js"
integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
crossorigin="anonymous"></script>
$.ajax("https://randomuser.me/api/?results=50").then(function (data) {
console.log(data.results);
});
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
Ecrivez du JS, sauvez, rechargez le navigateur (console ouverte) :
window, le couteau suisse
var test = window.prompt("blabla");
Ecrivez du JS, sauvez, rechargez le navigateur (console ouverte) :
window, le couteau suisse
var test = window.document.getElementById("item");
test.innerHTML = "<strong>coucou</strong>";
Rien n'est sacré en JavaScript, rien n'est jamais certain.
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...
Bujo: les habitudes de la semaine
<div id="app"></div>
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...
Bujo: la todolist quotidienne
Bujo: aller plus loin
window.localStorage.setItem("prenom", "Marcel");
Sauver / Enregistrer
Retrouver / Charger
var prenom = localStorage.getItem("prenom");
if (prenom) {
console.log("bonjour " + prenom);
}
Youtube kids
// modifier le style du body
document.body.style.backgroundColor = "blue";
Bonus:
JavaScript Object Notation
@see https://fr.wikipedia.org/wiki/JavaScript_Object_Notation
Douglas Crockford
window.JSON.parse('{"toto": "titi"}');
window.JSON.stringify({toto: "titi"});
Warning: fonctions et structures circulaires/récursives interdites
localStorage + JSON
Bonus:
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
cherchez l'erreur
Bonus:
+ setTimeout + setInterval
// setTimeout::(function, number)->id
setTimeout(function () {
alert("28 secondes plus tards..")
}, 28000);
setTimeout: le delai
// setInterval::(function, number)->id
var intId = setInterval(function () {
alert("Toutes les secondes");
}, 1000);
clearInverval(intId);
setInterval: la boucle
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.
ou bubbling
document.body.addEventListener("click", function (event) {
console.log(event.target); // le "sous-élement" cliqué
console.log(event.currentTarget); // le body
});
document
.querySelector("span")
.addEventListener(function (e) {
console.log(e);
e.stopPropagation(e);
});
window
.addEventListener(function (e) {
console.log(e);
e.preventDefault();
});
d'évènement
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
à découvrir de votre côté
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"));}
}
THANK'S EVERYONE
It's finally done ! See you soon
By Loïc TRUCHOT
Introduction à JavaScript, en français et sans compromis.