ECMAScript

{firstname:'Stéphane' ,
 lastname : 'Michel',
 job: 'Software craftsman'}

© Stéphane Michel

Sommaire / Concepts clefs

SOMMAIRE

ECMAScript

Standardisé par ECMA International (https://www.ecma-international.org/)

Langage de script orienté prototype 

Implémentations

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)

Classe vs Prototype

  • Une classe définie par son code source est statique ;
  • Elle représente une définition abstraite de l'objet ;
  • Tout objet est instance d'une classe ;
  • L'héritage se situe au niveau des classes.
  • Un prototype défini par son code source est mutable ;
  • Il est lui-même un objet au même titre que les autres ;
  • Il a donc une existence physique en mémoire ;
  • Il peut être modifié, appelé ;
  • Il est obligatoirement nommé ;
  • Un prototype peut être vu comme un exemplaire modèle d'une famille d'objet ;
  • Un objet hérite des propriétés (valeurs et méthodes) de son prototype.

Prototype

Première classe en JavaScript

C'est plus sympa en ES2016 / ES7

ES2015, ES2016, ES2017

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 

Quelle version d'ES ?

Couverture de la norme ES

Navigateurs récents

Support de 96% à 100%.

Serveurs

Node LTS à 99%.

Mais sinon…?

É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 !

State Of JS

Notions de base

Types de données

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...

== vs ===

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

Object

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]]

let & const

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...

let & const

et ici

var c'est le mal !

Exemple interactif ici

Template string

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>`

Fonctions fléchées

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

Détail ici et ici

Contrairement aux functions, les fonctions fléchées ne redéfinissent pas le this ce qui entraine des comportements différents... voir ici ou ici pour plus de détails sur this/call/apply/bind

Littéraux et Objets

Exemple interactif ici

Littéraux et Objets

Exemple interactif ici

Nommage dynamique d'attributs

Littéraux et Objets

Exemple interactif ici

Tableaux, fonctions et nom d'attributs par défaut

Littéraux et Objets

Et tout ça ensemble...

Classes

Déclaration, héritage, static, getter, setter et valeur par défaut

Les opérations fun

Destructuration

Destructuration

Sur les littéraux et les tableaux

Destructuration

Code interactif ici

Paramètres des fonctions

Valeurs par défaut

Code interactif ici

Sur paramètres des fonctions et destructuration d'objets

Rest & Spread

REST

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

Operations sur les iterables

Itérer

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

map / reduce / filter

map

const result = items.map((item) => {...})

Construit un tableau à partir d'un tableau

Filter

const result = items.filter((item) =>{
     return condition
})

Permet de filtrer les éléments d'un tableau

Reduce

const result = items.reduce(
   (accumulator, currentValue) =>{
     return...
   },
   initialValue
)

Construit un objet à partir d'un tableau

Créer ses modules

Doc sur les modules ici ou ici

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()

2 syntaxes

node --experimental-modules main.mjs

Support 'experimental' de la synaxe 

node  main.js

Voir ici pour le mode expérimental

Programmation asynchrone

Parce que gaspiller c'est mal !

Pourquoi l'asynchronisme ?

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

 

 

 

 

Callback

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

Callback : exemple

Code interactif ici 

Callback hell

Code interactif ici 

Autre limite des callback

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.

 

Promise

const promesse = new Promise(
    (resolve,reject) => {
       // si OK 
       resolve(result)
       // si KO
       reject(error)
})

Plus de détails ici et ici

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.

Promise : exemple

Code interactif ici 

async / await

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)
    ...
}

Attention : ne fait pas bon ménage avec Array.forEach() voir ici et ici

Promess vs async/await ici

async / await : exemple

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)}`)

  }

})()
 

Bibliographie

https://oncletom.io/node.js/chapter-03/index.html​

Node.js • Apprendre par la pratique • Chapitre 3 sur Javascript • Thomas Parisot

https://developer.mozilla.org/fr/docs/Web/JavaScript/Guide​

Guide Javascript • Fondation Mozilla

JavaScript

Livres en ligne gratuits

Sites

ES6

https://babeljs.io/docs/en/learn​

Learn ES2015 • babeljs.io

https://leanpub.com/understandinges6/read​

Understanding ECMAScript 6 • Nicholas C. Zakas

http://exploringjs.com/es6/​

Exploring ES 6 • Dr. Axel Rauschmayer

Livres en ligne gratuits

Sites

https://tech.mozfr.org/tag/ES6%20en%20détails

ES 6 en détail (en français) • Mozilla francophone

ES6

Vidéo

https://jskatas.org/#bundle-es6-katas

Javascript Katas jskatas.org

Katas (entrainement avec du vrai code)

Async / await

https://morioh.com/p/ffc9ab6c004a

Top 5 Common Node.js mistakes in Lambda  Hanamichi Sakuragi

Divers

Sites

https://github.com/nmussy/javascript-style-guide​

Airbnb JavaScript Guide de Style - traduction française Jimmy Gaussen

https://github.com/airbnb/javascript

Airbnb JavaScript Style Guide  Airbnb

https://morioh.com/p/9f2ba53e50ef

How to make tests using chai and mocha Cristian Vasta

Made with Slides.com