vue d'ensemble
Prérequis pour les formations CGI:
Browser
Rendering engine
APIs
JavaScript Engine
// initialise le DOM
// accès au DOM
// accès à AJAX
// ...
(liée aux coûts de dev.)
Contenu
Comportement
Style
en ligne...
1 + "1"
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 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)
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 // ???
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
(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)
}
(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
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 closures (ou "fermetures lexicales")
Une fonction peut compter sur plusieurs variables prédéfinies:
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");})();
"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"...
(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
...
try {
nonExistentFunction();
} catch (error) {
console.error(error);
// expected output: ReferenceError: nonExistentFunction is not defined
// Note - error messages will vary depending on browser
}
(la partie ardue)
souvent: "OOJS"
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.sayHello();
// Hello, my name is Disaster Girl
Mais c'est quoi au juste un prototype?
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
// 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"
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
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...
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;
}
}
(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é...)
(la partie cool)
(Je ne ferais pas mieux que ça...)
let myTimeout = setTimeout(
()=>{console.log("now!")},
2000,
);
let myInterval = setInterval(
()=>{console.log("now!")},
2000,
);
clearTimeout(myTimeout);
clearInterval(myInterval);
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);
});
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);
});
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;
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;
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...)
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
TODO
TODO
c'est compliqué...
et frameworks
(je veux faire une app cliente moi...)
npm install -g @angular/cli
ng new testNG
cd testNG
(C'est quoi la programmation reactive?)
npm install -g @ionic/cli
ionic start testIonic tabs
cd testIonic
et le dev. en remote
SSH serveur | fr02-9900wl4cli |
port | 2201 |
user | node |
pasword | node |