JavaScript et TypeScript
vue d'ensemble
/
Objectifs
Prérequis pour les formations CGI:
- Browser
- DOM, Ajax...
- langage JS
- POO en JS
- asynchronisme en JS
- langage TS
- Ecosysteme
- npm
- web frameworks
- Hybrid et Ionic
Les navigateurs
- fonctionnement
- fonctionnalités
- comme outil de développement
Le web aujourd'hui...
le navigateur...
Browser
Rendering engine
APIs
JavaScript Engine
// initialise le DOM
// accès au DOM
// accès à AJAX
// ...
le DOM et (beaucoup) d'APIs
Un IDE parfait...
Une philo...
(liée aux coûts de dev.)
Contenu
Comportement
Style
lançant des... IDEs
en ligne...
La partie pas cool...
JavaScript
Création
- créé en 1995
- standardisé en ECMAScript (ECMA-262)
- version actuelles:
- ES5.1 : 2011
- ES6 : 2015
Aujourd'hui
- 12 millions de dev...
- rendu rapide par V8
- plus grand repo logiciel (tous langages confondus)
Les variables
- containers pour des "valeurs"
- garbage collector.
- les variables ne sont pas typées.
- MAIS, les valeurs, SI
- dynamiquement typé
- il existe 3 façons de déclarer une variable:
- const: à privilégier (lecture seulement)
- let: déclaration "liée au block".
- var: ...
Les valeurs
- les opérateurs ont la vilaine manie de caster les valeurs... (weakly typed)
- l'opérateur "typeof()" retourne le type d'une valeur
- il existe exactement 6 types (de valeurs):
- Undefined: undefined
- Null: null
- Boolean: true, false
- Number: 42 .33 NaN Infinity
- String: "double quoted" or 'single quoted'
- Object:
1 + "1"
Les objets
les objets sont des références vers des
"dictionnaires / tableaux associatifs / tables de hachage"
object_var
ref: 0x123456
string_var
"ma chaine de caractères"
addr: 0x123456
x | |
---|---|
y |
"une autre chaine"
42
object_var2
ref: 0x123456
Les objets
les objets sont des collections de propriétés.
les propriétés sont des containers pour des valeurs...
// variable and primitive value
let x = "Hello";
// variable et objet
let tab = {
y: "test",
z: 42
};
x; // "Hello"
tab; // (the object ref)
tab.y; // "test"
tab["y"]; // "test"
tab.y === tab["y"]; // true (NB: triple equal)
initialisation des objets
les objets sont mutables (toujours):
let x = {
prop1: "a",
prop2: 42
}
let y = x;
let z = new Object();
z.prop1 = "a";
z.prop2 = 42;
Object.is(x,y)
Object.is(x,z)
x === y // ???
x === z // ???
Les tableaux
- Les tableaux sont des objets (de type "Array")
- indexés à partir de 0
- stockent des valeurs hétérogènes.
var arr = [ "test", 1234, {}, [], "hi" ];
arr.push("sixth"); // 6
arr.length; // 6
arr[5]; // "sixth"
arr[7] = 012; // 10
arr.length; // 8
arr[6]; // undefined
arr[7]; // 10
arr[8]; // undefined
arr.length; // 8
Les tableaux
(et les boucles)
// les tableaux se parcourent avec .forEach()
let fruits = ['Apple', 'Banana'];
fruits.forEach(function(item, index, array) {
console.log(item, index);
});
// Apple 0
// Banana 1
// ou "for...of"
for (let f of fruits){
console.log(f.length)
}
Les tableaux
(et les boucles)
// les tableaux se parcourent avec .forEach()
let fruits = ['Apple', 'Banana'];
fruits.forEach(function(item, index, array) {
console.log(item, index);
});
// Apple 0
// Banana 1
// ou "for...of"
for (let f of fruits){
console.log(f.length)
}
/*******************
* ATTENTION *
* *****************/
// les propriétés sont parcourues avec for...in
let obj = {x:1, y:2};
for (let prop in obj){
console.log(prop);
}
// x
// y
Les fonctions
- Les fonctions sont des objets (de type "Function")
- les signatures ne sont PAS vérifiées.
function add(x,y){
return x+y;
}
add(1,2); // 3 ...
add(1); // NaN: comme 1 + undefined
add(1,2,3); // 3 (outch)
// fonctions variadiques
function add(){
let s = 0;
for (let arg of arguments){
s += arg
}
return s;
}
// ou (plus moderne)
function add(...args){
let s = 0;
for (let arg of args){
s += arg
}
return s;
}
Les fonctions
les closures (ou "fermetures lexicales")
Une fonction peut compter sur plusieurs variables prédéfinies:
- les arguments (y compris la variable "arguments")
- this (wait for it...)
- TOUTES les variables de son scope et des scopes parents.
Les fonctions
les IIFEs
Une fonction est souvent définie pour un usage immédiat.
(et profiter des closures)
On appelle ça une Immediately Invoked Function Expression
// on voudrait raccourcir:
function toto(){console.log("toto");}
toto();
// en
function toto(){console.log("toto");}();
// mais en fait, il faut faire ça...
(function toto(){console.log("toto");})();
les fonctions fléchées
"arrow functions"
let tab = [1,2,3,4]
tab.forEach(function (i){
console.log(i+1);
});
let tab = [1,2,3,4]
tab.forEach((i) => {console.log(i+1);});
tab.map((i)=>i+1).forEach((i)=>console.log(i));
// les arrows functions peuvent se passer d'accolades
// et de return
// si la partie droite est une expression (pas une instruction)
Ne sont pas "hoisted"...
let vs var
(un problème de fermeture lexicale)
for (let i = 0; i < 10; i++) {
setTimeout(() => {
console.log(i);
}, 1);
}
> 0
> 1
> 2
...
for (var i = 0; i < 10; i++) {
setTimeout(() => {
console.log(i);
}, 1);
}
> 10
> 10
> 10
...
la gestion des exceptions
- les erreurs sont ... des objets. (de type "Error")
-
propriétés:
- message
- fileName
- lineNumber
- beaucoup d'erreurs standards
- sinon, c'est comme en Java.
try {
nonExistentFunction();
} catch (error) {
console.error(error);
// expected output: ReferenceError: nonExistentFunction is not defined
// Note - error messages will vary depending on browser
}
La programmation orientée objet
(la partie ardue)
JavaScript
La POO en JS
souvent: "OOJS"
- JS est un langage où TOUT est objet.
- vous aviez remarqué
- Mais c'est un langage sans vraies classes !!!
le prototypage
- JS est un langage orienté "prototype".
- ce mécanisme remplace les classes et l'héritage.
- quand on tente d'accéder à une propriété sur un objet, l'objet est inspecté en premier lieu. Si absente, on tente d'accéder à cette propriété sur son prototype...
- (et récursivement... jusqu'à "Object")
Définir ses propres types
function Meme(name, url){
this.name = name;
this.url = url;
this.funLevel = 5;
}
let disasterGirl = new Meme("Disaster Girl", "https://i.imgflip.com/4yionv.jpg")
Avec ses méthodes
Meme.prototype.sayHello = function sayHello(){
console.log("Hello, my name is " + this.name);
};
disasterGirl.sayHello();
// Hello, my name is Disaster Girl
Mais c'est quoi au juste un prototype?
un dessin?
un exemple?
function Meme(name, url) {
this.name = name;
this.url = url;
this.funLevel = 5;
}
let disasterGirl = new Meme(
"Disaster Girl",
"https://i.imgflip.com/4yionv.jpg");
Meme.prototype.sayHello = function sayHello(){
console.log("Hello, my name is " + this.name);
};
disasterGirl.__proto__; // an object with a "sayHello" property
disasterGirl.constructor === Meme; // true
disasterGirl.constructor.prototype === disasterGirl.__proto__; // true
disasterGirl.__proto__.__proto__ === Object.prototype; // true ^^
disasterGirl.__proto__.__proto__.constructor === Object; // true
"this" is a trap...
- "this" fonctionne différemment en JS.
- Il représente l'objet "sur lequel est appelé la fonction".
// en théorie tout va bien
function Person(name){
this.name = name;
}
Person.prototype.sayHello = function (){
console.log("Hello, my name is " + this.name);
}
let toto = new Person("Toto");
toto.sayHello(); // "toto" devient "this"
"this" is a trap...
Vous connaissez la différence entre la théorie et la pratique? :p
let say = toto.sayHello;
say() // TypeError: "this" is undefined
///////////////////////////
// sinon, on peut faire ça:
//
say.call(toto);
// ou ça:
let totoHello = Person.prototype.sayHello.bind(toto);
totoHello();
totoHello();
function CategorizedMeme(name, url, category) {
Meme.call(this, name, url);
this.category = category;
}
let meme2 = new CategorizedMeme('Distracted Boy', 'myurl', 'funny');
meme2.category === 'funny';
meme2.name === 'Distracted Boy';
meme2.funLevel === 5;
meme2.sayHello === undefined; // (╯°□°)╯ ︵ ┻━┻
Object.setPrototypeOf(
CategorizedMeme.prototype,
Meme.prototype
);
meme2.sayHello(); // inheritance... at last
et si on devient...
Hahaha, je vous ai eu...
class Toto{
constructor(name){
this.name = name;
}
}
let toto = new Toto("Toto");
toto.constructor.prototype === toto.__proto__; // true
class Titi extends Toto{
constructor(name, x){
super(name);
this.x = x;
}
}
let titi = new Titi("Titi", 42);
titi.__proto__.__proto__.constructor === Toto
Merci ES6...
Retour à la maison...
class Person{
constructor(firstName, lastName){
this.firstName = firstName;
this.lastName = lastName;
}
// methodes
sayHello(){
console.log("Hello, I'm " + this.firstName);
}
// static
static staticProperty = 'someValue';
static staticMethod() {
return 'static method has been called.';
}
// accesseurs
get completeName(){
return this.firstName + " " + this.lastName;
}
}
L'objet global
- dans les navigateurs, c'est "window"
- dans nodeJS, c'est "global"
- "window" permet d'accéder à la fenêtre du navigateur
- "window.document" permet d'accéder au DOM
- souvent abrégé en "document"
Modification du DOM
- document.querySelector()
- document.createElement()
- element.textContent
- element.appendChild()
- element.parentNode
- element.setAttribute()
- surtout "class"
- ...
L'héritage multiple
(les mixins)
let calculetteMixin = Base => class extends Base {
calc() { }
};
let aleatoireMixin = Base => class extends Base {
randomiseur() { }
};
class Toto { }
class Truc extends calculetteMixin(aleatoireMixin(Toto)) { }
(j'étais obligé...)
- les classes peuvent être anonymes
- (comme les fonctions)
- générer les classes dynamiquement permet de "contourner" les limitations.
L’asynchronisme
(la partie cool)
JavaScript
C'est quoi "asynchrone"?
- Une forme d’exécution de plusieurs tâches en concurrence.
- (pas de parallélisme)
- collaboration active des tâche pour éviter bloquer le thread unique.
- tâches misent en file d'attente.
Le tuto officiel est un bijou
(Je ne ferais pas mieux que ça...)
Le langage
- JS n'est pas "asynchrone" en soi.
- c'est un langage impératif
- Ce sont ses librairies qui le rendent ainsi.
- du fait de son usage de départ (le navigateur)
- (mono-thread)
- Toutes les I/O sont non-bloquantes.
Attendre...
let myTimeout = setTimeout(
()=>{console.log("now!")},
2000,
);
let myInterval = setInterval(
()=>{console.log("now!")},
2000,
);
clearTimeout(myTimeout);
clearInterval(myInterval);
Les callbacks
premier mécanisme de gestion asynchrone
let tacheLongue = ()=>{
setTimeout(
()=>{
console.log("c'était long...")
},
2000
);
}
let txt = "je veux exécuter ça APRES!"
tacheLongue();
console.log(txt);
let tacheLongue = (cb)=>{
setTimeout(
()=>{
console.log("c'était long...");
cb();
},
2000
);
}
let txt = "je veux afficher ça APRES!";
tacheLongue(()=>{
console.log(txt);
});
error-first callbacks
let tacheLongue = (cb)=>{
try {
setTimeout(
()=>{
console.log("c'était long...");
cb();
},
2000
);
} catch (error){
cb(error);
}
}
let txt = "je veux afficher ça APRES!";
tacheLongue((err)=>{
if (err){
console.log("Oups");
return;
}
console.log(txt);
});
Les Promises
Les Promises
- second mécanisme de gestion de l'asynchronisme.
- un objet encapsulant un traitement en cours.
let done = true;
let maPromise = new Promise((resolve, reject)=>{
setTimeout(
() => {
if (done)
resolve("done était vrai")
else
reject("done était faux")
},
2000,
);
});
maPromise
.then(resultat1 => '""" ' + resultat1 + ' """' )
.then(resultat2 => {console.log('au final: ' + resultat2)})
.catch(raison => {console.log('raté: ' + raison)})
async/await
- s'est juste un usage de Promise intégré dans la syntaxe.
- pas un nouveau mécanisme
- (OK, JS est un petit peu un "langage asynchrone" maintenant...)
-
une "async" fonction asynchrone renvoie TOUJOURS une Promise
- implicitement ou pas...
-
dans les fonctions "async", on peut utiliser "await".
- qui revient à utiliser ".then()"
- un try...catch correspond à un ".catch()"
et tout redevient lisible...
let done = true;
let maPromise = new Promise((resolve, reject)=>{
setTimeout(
() => {
if (done)
resolve("done était vrai")
else
reject("done était faux")
},
2000,
);
});
maPromise
.then(resultat1 => '""" ' + resultat1 + ' """' )
.then(resultat2 => {console.log('au final: ' + resultat2)})
.catch(raison => {console.log('raté: ' + raison)})
et tout redevient lisible...
let done = true;
let maPromise = new Promise((resolve, reject)=>{
setTimeout(
() => {
if (done)
resolve("done était vrai")
else
reject("done était faux")
},
2000,
);
});
maPromise
.then(resultat1 => '""" ' + resultat1 + ' """' )
.then(resultat2 => {console.log('au final: ' + resultat2)})
.catch(raison => {console.log('raté: ' + raison)})
let done = true;
async function traitement1(){
if (done)
return "done était vrai"
else
throw "done était faux"
}
async function traitement2(){
try {
let resultat = await traitement1();
console.log('""" ' + resultat + ' """')
} catch (raison) {
console.log('raté: ' + raison)
}
}
traitement2();
(enfin, ça a l'air synchrone quoi...)
Où est le .setTimeout()?
- .setTimeout() utilise une callback, pas une Promise.
- il faut le "promisifier"
function later(delay){
return new Promise(resolve => setTimeout(resolve, delay))
}
async function process(){
await later(2000);
console.log("TADAAAAAA!!!");
}
process();
// ou, avec nodeJS
let util = require('util')
let later = util.promisify((delay, f) => setTimeout(f, delay))
// fait pour les fonctions dont la callback est le dernier argument
// comme toujours en NodeJS
AJAX
- Définition...
- lié aux I/O donc -> asynchrone
- les navigateur ont une API "fetch"
Event handlers
Object destructuring
TODO
@Decorators
TODO
"JavaScript that scales"
TypeScript
C'est quoi TypeScript?
- Un superset strict de JS
- dans sa dernière version
- avec des types
- "transpile" dans la version de JS désirée
- absorbe désormais l'essor de JS
- "nécessaire" pour certains frameworks.
- notamment Angular
Import / export
c'est compliqué...
Ecosystème
et frameworks
Pourquoi j'ai besoin de nodeJS?
(je veux faire une app cliente moi...)
Angular
npm install -g @angular/cli
ng new testNG
cd testNG
RxJS
(C'est quoi la programmation reactive?)
RxJS
C'est quoi une app "hybride"?
Ionic
npm install -g @ionic/cli
ionic start testIonic tabs
cd testIonic
VSCode
et le dev. en remote
SSH serveur | fr02-9900wl4cli |
port | 2201 |
user | node |
pasword | node |
Learn by doing...
Merci de votre attention
JS/TS
By Olivier DUPOUY
JS/TS
knowledge about front-end languages and basic tools.
- 107