Cyrille Perois
Front-end architect @ w3r.one
Programmation web - Client riche
Les différentes parties
Le langage et ses API
L'environnement dans lequel on l'exécute (API spécifiques)
Ce qu'on va explorer ensemble
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Hello world</title>
<script type="module" src="./app.js"></script>
</head>
<body>
<h1>Hello world</h1>
</body>
</html>monprojet ├── app.js └── index.html
// Les commentaires sur une seule ligne
/*
les commentaires
sur plusieurs lignes
*/// Déclaration de la variable
let myVariable
// Affectation d'une valeur
myVariable = "Hello, world !"
// Déclaration et affectation
let myFirstVar = "Hello"
// Réassignation de la valeur d'une variable
let myVariable = "Hello world !"
myVariable = "Vous voulez un whisky ?"// Déclaration et affectation
const myVariable = "Hello, world !"
const hello = "Hello world !"
hello = "Vous voulez un whisky ?"
// => ReferenceError
// Impossible de réaffecter une constanteVous verrez peut-être des scripts utiliser le mot-clef var pour déclarer une variable. C'est l'ancienne méthode. Oubliez totalement ce mot-clef, qui est aujourd'hui remplacé par let
JS est un langage à typage dynamique et faible.
Le type d'une variable est donc :
const integer = 8000
const decimal = 123.456
// addition
8000 + 42 // => 8042
// soustraction
8000 - 42 // => 7958
// multiplication
13 * 37 // => 481
// division
8000 / 42 // => 190.476190476
// exponentiation
2 ** 3 // => 8 (2 puissance 3, quoi)
8000 / 0 // => Infinity
-8000 / 0 // => -Infinity
"Everything but a number" / 8000 // => NaN
"Everything but a number" / 8000 + 42 // => NaN"Hello, world !"
'Hello, world !'
`Hello, world !`
const who = "world";
"Hello, " + who + " !"
`Hello ${who} !`
// => "Hello, world !"
`The result of 1 + 1 is ${1 + 1}`
// => "The result of 1 + 1 is 2"const ok = true
const notOk = falseconst nullValue = nulllet undefinedValue
console.log(undefinedValue) // => undefined
const explicitUndefined = undefinedOn a le conteneur (la variable) et quelque chose de vide dedans (null)
On a le conteneur (la variable), mais absolument rien dedans (undefined)
const me = {
firstname: "Cyrille",
age: 28
}
me.firstname // => "Cyrile"
me.age // => 28
me.firstname = "George"
me.firstname // => "George"
me.job = "developer and teacher"
me.job // "developer and teacher"const number = 123.456
number.toFixed(2) // => 123.46
const str = "Hello world !"
str.toUpperCase() // => HELLO WORLD !const name = prompt("What's your name ?")
if (name === "Cyrille") {
alert("Me too !")
} else if (name === "Toto") {
alert("Srsly?")
} else {
alert(`Hello ${name} !`)
}10 < 20 // => true
10 <= 20 // => true
20 > 10 // => true
20 >= 10 // => true
20 == 20 // => true
10 != 20 // => true
"hello" == "hello" // => true
"hello" != "world" // => true10 == "10" // => true
20 != "20" // => false😱
10 === "10" // => false
20 !== "20" // => true🤗
Privilégier les opérateurs stricts (=== et !==) pour éviter la conversion implicite de type
true && true // => true
true && false // => false
true || true // => true
true || false // => true
false || false // => false
!true // => false
!false // => true10 && "hello" // => "hello"
0 && "hello" // => 0
10 || "hello" // => 10
0 || "hello" // => "hello"
!"hello" // => falseConversion automatique des valeurs en booléen afin de déterminer si la valeur "correspond" à true (valeur truthy) ou false (valeur falsy)
Renvoi de la première (||) ou de la dernière (&&) valeur truthy
let i = 0
while (i < 10) {
console.log(i)
++i
}
let j = 0
do {
console.log(j)
++j
} while (j < 10)
for (let k = 0; k < 10; ++k) {
console.log(k)
}
// => 0 1 2 3 4 5 6 7 8 9const addTwoNumbers = (number1, number2) => {
return number1 + number2
}
const addTwoNumbers = (number1, number2) => number1 + number2
addTwoNumbers(8000, 42) // => 8042const sayHello = (who = "World") => {
return `Hello ${who}`
}
sayHello("Tom") // => Hello Tom
sayHello() // => Hello World
sayHello(null) // => Hello
sayHello(undefined) // => Hello WorldLa valeur par défaut d'un paramètre est utilisée si ce paramètre reçoit la valeur undefined (explicitement ou implicitement)
const addNumbers = (number1) => {
const addNumber1ToNumber2 = (number2) => {
return number1 + number2
}
return addNumber1ToNumber2
}
const add3 = addNumbers(3)
add3(2) // => 5 (3 + 2)
addNumbers(3)(2) // => 5Une fonction crée à l'intérieur d'une autre fonction a accès au scope de sa fonction parent (même une fois que la fonction parent a return). On appelle cette fonction une "fermeture" ou "closure"
const applyFunctionOnValue = (value, f) => {
return f(value)
}
const add2 = (n) => n + 2
applyFunctionOnValue(2, add2) // => 4 (2 + 2)
applyFunctionOnValue(2, (n) => n + 2) // 4Les fonctions sont des valeurs comme les autres : on peut les passer en paramètre d'une fonction
Il existe aussi le mot-clef function pour définir une fonction. Il faut l'avoir en tête, mais nous n'utiliserons que les fonctions fléchées, parce qu'elles sont plus récentes et apportent moins de concepts obscurs et implicites avec elles
const emptyArray = []
const animals = ["cat", "dog", "mouse"]
animals[0] // => "cat"
animals[1] // => "dog"
animals[2] // => "mouse"
animals.length // => 3
animals[1] = "parrot"
animals.push("rat")
// => ["cat", "parrot", "mouse", "rat"] (modifie le tableau)
[...animals, "rat"]
// => ["cat", "parrot", "mouse", "rat"] (crée un nouveau tableau)
["rat", ...animals]
// => ["rat", "cat", "parrot", "mouse"] (crée un nouveau tableau)
animals.slice(0, 2)
// => ["cat", "parrot"] (nouveau tableau)const fruits = ["Apple", "Banana", "Strawberry"]
for (let i = 0, length = fruits.length; i < length; ++i) {
console.log(fruits[i])
}
for (let fruit of fruits) {
console.log(fruit)
}
fruits.forEach((fruit) => console.log(fruit))
// => "Apple" "Banana" "Strawberry"
fruits.map((fruit) => fruit.toUpperCase())
// => ["APPLE", "BANANA", "STRAWBERRY"] (nouveau tableau)Un fichier JS est un module, et on peut définir ce que ce module expose au monde extérieur en exportant les valeurs qu'on veut :
export const add = (a, b) => a + b
export const difference = (a, b) => a - b
export const multiply = (a, b) => a * bOn peut ensuite importer ces valeurs à partir d'un autre module :
import { add, difference } from "./math.js"
const mySuperComplicatedFunction = () => {
// do some complicated stuff
const resultAdd = add(3, 2)
const resultDifference = difference(2, 3)
}Les exports d'un module peuvent être de deux types :
const add = (a, b) => a + b
export default addimport add from "./math.js"
add(3, 2)Nous préférerons nous contenter des exports nommés. Ils nous garantissent une meilleure stabilité dans les noms utilisés à travers les modules, donc une plus grande facilité de refactoring.
Les exports par défaut existent principalement pour des raisons de compatibilité avec le système de modules CommonJS, utilisé par NodeJS avant que les modules standards n'aient vu le jour
Nous n'utiliserons pas à 100% le système de modules natif, car l'implémentation n'est pas encore optimale dans les navigateurs. On utilisera la syntaxe, mais on utilisera un bundler (Parcel) pour compiler nos modules en bundles prêts à être envoyés dans le navigateur.
By Cyrille Perois