{firstname:'Stéphane' , lastname : 'Michel', job: 'Software craftsman'}
© Stéphane Michel
Standardisé par ECMA International (https://www.ecma-international.org/)
Langage de script orienté prototype
ActionScript Flash
JavaScript
JScript (Microsoft)
= ECMAScript
déc. 1995 | JavaScript 1.0 (en 10 jours par Brendan Eich). Netscape Navigator 2.0ß3 en 12/95 |
---|---|
déc. 1999 | ES3. JScript 1.5 à peu près à ce niveau (IE4–8) |
Un peu d'histoire
déc. 2009 (!) | ES5. Baseline de compat’ actuelle. IE9+, Node, etc. Peu de gros changements. |
---|---|
juin 2015 | ES2015 / ES6. Énormément de nouveautés de langage pur. |
juin 2016 | ES2016 / ES7 (versions annuelles désormais, dans le cadre d’ES.Next) |
juin 2017 | ES2017 / ES8 (async/await, Shared memory & atomics, Object.values/entries, String#padStart/End…) |
juin 2018 | ES2018 / ES9 (Rest/Spread properties, plein de trucs RegExp, Promise#finally et d’autres trucs cool) |
Première classe en JavaScript
C'est plus sympa en ES2016 / ES7
Au final comme personne ne comprend rien aux prototypes, ES6 a introduit un ensemble de mots clefs, simple sucre syntaxique mais qui ont contribué à son adoption et à sa popularité surtout chez les anciens "Javaistes"...
Plus de détails ici
Support de 96% à 100%.
Node LTS à 99%.
Évidemment il reste IE (9–11) (11%)
Du coup que fais-je ?
Convertit ECMAScript 2015 et + en ES5
ES5 est supporté quasi partout (Navigateur et Environnements node.js)
Du coup on utilise la dernière version d'ES pour coder !
Number : Entier, réel, etc.
Exemple : 2, 2.5, +Infinity, -Infinity, NaN
String : Chaîne de caractères entourée par ', " ou `
boolean : true/false
null : absence de valeur
undefined : valeur inconnue
Complément ici
symbol : Les symboles sont des valeurs que les programmes peuvent créer et utiliser comme des clés de propriétés sans risquer de rentrer en collision avec les noms déjà utilisés....détaillé ici
et le dernier arrivé avec ES6...
42 == '42' // => true -- Argh, ça sent le PHP, là… null == undefined // => true -- hmmm… null == 0 // => false -- heureusement ! 0 == undefined // => false -- heureusement ! 0 == false // => true -- Façon C… 1 == true // => true -- Façon C… 42 == true // => false -- Watcha ?! (x == ToNumber(y), ES3 §11.9.3) '0' == false // => true -- Woah ! '' == false // => true -- Yowza ! NaN == NaN // => false -- Bin oué, c’est le principe… // avec ===, fini de jouer : vérification de la valeur ET du TYPE ! 42 === '42' // => false null === undefined // => false null === 0 // => false 0 === undefined // => false 0 === false // => false '0' === false // => false NaN === NaN // => false -- rien à faire !
Source delicious insight
Array : [1, 'a', {e:'valeur}, 4, 6]
const myObject = { titre: 'node.js', isbn: '978-2212139938', published: false, auteur: 'Thomas Parisot'}
Complément ici
Function : function somme(a, b){ return a+b}
Date : const now = new Date()
RegExp : const re = new RegExp('\\w+')
Map : [[1, 'a'], [2,{e:'valeur'}], [3, 6]]
const is the new var,
utilisez let seulement si réaffectation (relativement rare)
Portée : le bloc
const n'est pas immutable !
utiliser Object.freeze() si besoin.
Une bonne raison de préférer const/let à var ici
Rappel : la portée de var est la fonction la plus proche (ou à défaut le contexte global), pas le bloc courant !
Pratique dans une page HTML/JavaScript "old school" mais c'est tout...
et ici
var c'est le mal !
Exemple interactif ici
Permet de simplifier la construction des chaînes de caractères
const arbre = 'pin' const action = 'heurtant' const chaine = `<p>Oh ! les cimes des ${arbre} grincent en se ${action}</p>`
Plus lisible que les functions
const max = (a,b) => a>b ? a : b max(4,5) // 5 ['a', 'b', 'c'].map((item, pos) => {item, pos})
Similaire à ce que l'on trouve en C# ou encore en Java8
Exemple interactif ici
Exemple interactif ici
Nommage dynamique d'attributs
Exemple interactif ici
Tableaux, fonctions et nom d'attributs par défaut
Et tout ça ensemble...
Déclaration, héritage, static, getter, setter et valeur par défaut
Sur les littéraux et les tableaux
Code interactif ici
Paramètres des fonctions
Code interactif ici
Sur paramètres des fonctions et destructuration d'objets
Récupère sous forme d'un tableau ou d'un littéral les paramètres non assignés
Forcement placé comme dernier paramètre
REST
Bien évidemment utilisable comme paramètre de function
SPREAD
Recopie de littéraux ou de tableaux
Code interactif ici
(pourquoi dans une console Javascript et pas dans une console node ?)
SPREAD
Un peu plus loin...
Code interactif ici
spread vs Object.assign ici
for (let i=0; i<10 ; i++) {...} for (let item of items){...} items.forEach((item) => {...})
for (let prop in object){...}
Iteration sur les propriétés d'un objet
const result = items.map((item) => {...})
Construit un tableau à partir d'un tableau
const result = items.filter((item) =>{ return condition })
Permet de filtrer les éléments d'un tableau
const result = items.reduce( (accumulator, currentValue) =>{ return... }, initialValue )
Construit un objet à partir d'un tableau
Par défaut, utilisation de commonJS
//------ ./lib.js ------ function foo() { ... } exports.foo = foo
//------ ./main.js ------
const lib = require('./lib')
lib.foo()
//------ ./lib.mjs ------ function foo() { ... } export foo
//------ ./main.mjs ------
import {lib} from './lib'
lib.foo()
node --experimental-modules main.mjs
Support 'experimental' de la synaxe
node main.js
Voir ici pour le mode expérimental
Parce que gaspiller c'est mal !
Parce que la programmation synchrone classique gâche les ressources CPU en passant son temps à attendre que le résultat des opérations arrive (I/O disque, réseau, appel hardware, interactions utilisateurs, etc.).
Alternatives classiques : parallélisme et multi-threading
On lance un traitement en fournissant une fonction à appeler lorsque le traitement sera terminé.
En attendant, on continue l'exécution du code.
function doAsync(param, callback){ // mon traitement ... if (ok){ callback(err) } else { callback(null, result) } }
function monCallback(error, result)
Par convention un callback a 2 paramètres
Code interactif ici
Code interactif ici
Toute exception levée dans un callback (i.e. non catchée dans celui-ci) va faire planter le thread et donc globalement planter le process.
const promesse = new Promise( (resolve,reject) => { // si OK resolve(result) // si KO reject(error) })
Représente la complétion ou l'échec d'une opération asynchrone
promesse.then(result => ...) // si resolve .catch(error => ...) // si reject
L'objet promesse est retourné immédiatement mais le résultat est obtenu plus tard, de manière asynchrone.
Code interactif ici
Inspiré du async / callback de C#
Basé sur les Promesses
Permet de rendre lisible les chaînes d'appels de fonctions asynchrones
À partir d'ES8 (et node 7 et +)
async function(){ const res1 = await callAsync1(param) const res2 = await callAsync2(res1) ... }
Promess vs async/await ici
const fs = require('fs') // Retourne une promesse qui retourne la liste des fichiers d'un répertoire const readDirWithPromise = path => {... } // Retourne une promesse qui retourne les propriétés (stats) d'un fichier const statWithPromise = file => {... } // Retourne une promesse qui extrait la date de création d'une propriété (un peu riche) const getBirthdateWithPromise = stat => {... } // Petite astuce pour pouvoir faire du async/await au niveau principal d'un script ;(async () => { const files = await readDirWithPromise('.') console.log('Resultat premiere promesse : ' + JSON.stringify(files)) // Attention ici un files.forEach ne fonctionne pas car Array.forEach n'est pas "async" for (const file of files) { const stat = await statWithPromise(file) console.log(`Resultat seconde promesse : ${JSON.stringify(stat)}`) const birthdate = await getBirthdateWithPromise(stat) console.log(`Resultat troisieme promesse : ${JSON.stringify(birthdate)}`) } })()
JavaScript
Livres en ligne gratuits
Sites
ES6
Livres en ligne gratuits
Sites
ES6
Vidéo
Katas (entrainement avec du vrai code)
Async / await
Divers
Sites