Upload
others
View
3
Download
0
Embed Size (px)
Citation preview
Le JS d'aujourdhui s'écrit avec les langages de demain : { TS || ES2015 }
Paul-Guillaume Déjardin@pgdejardin
@XebiaFr
Un peu d'histoire : De ES3 à ES5
● mai 1995 : Javascript 1 sur Netscape 2.0● juin 1997 : ECMAScript (ES1, ECMA-262) devient le standard officiel● dec 1999 : ES3 (IE 4-8)● nov 2005 : Projet Tamarin (ES4, Mozilla/Adobe) => Abandonné● dec 2009 : ES5 (IE9+, NodeJS), peu de changements● juin 2015 : ES6/ES2015 apporte beaucoup de nouveautés● juin 2016 : ES7/ES2016 en cours de ratification
@pgdejardin #moisdujs
@XebiaFr
● 90% à 98% des navigateurs dit "Evergreen" (Sauf Safari : 53%)● Node LTS v4.4.5 (50%), Node v5.11.1 (56%) et Node LTS v6.2.1 (93%)● Comment faire ?
Et maintenant ?
@pgdejardin #moisdujs
@XebiaFr
Babel !
● Transpile ES6 (sauf Proxies), ES7 vers ES5 ou ES3● Différents "presets" (ES2015, stage-0, etc…)● Différents "plugins" (ES3, ES5, ES2015, etc…)● En pratique fonctionne avec IE9+, Node, evergreens, etc…● Fonctionne avec… Tout ? (IDE, builders, tests, runtime, etc…)
@pgdejardin #moisdujs
@XebiaFr
Let et Const
@pgdejardin #moisdujs
function f() { { let x = 'start'; { console.log(x); // okay, block scoped name, x == start const x = 'sneaky'; console.log(x); // x == sneaky // error, const x = 'foo'; } // okay, declared with `let` x = 'bar'; // x == bar // error, already declared in block let x = 'inner'; }}
@XebiaFr
Const
● const ≠ immutable
@pgdejardin #moisdujs
const author = { name: 'Bob', language: 'js' };author.language = 'es6';
const days = ['tuesday', 'wednesday', 'thursday'];days.push('friday');
● Utiliser immutable.js
@XebiaFr
Fonctions Fléchées
● Ne redéfinit pas le this, arguments, super et new.target
@pgdejardin #moisdujs
this.getTodos().then(todos => this.setState({ todos }));
const onClickSlot = () => this.openSlot(this.slot);
const mapsToProps = (state, props) => { const hash = props.location.hash; return { hash, todos: state.todos };};
@XebiaFr
ES2015 : Les Objets et Classes
● Les littéraux avant :
@pgdejardin #moisdujs
const edit = (item, job) => ({ type: EDIT, payload: { item: item, job: job } });
function filter(name, field) { const result = {}; result[name] = 'Title'; result[field] = field; return result;}
@XebiaFr
ES2015 : Les Objets et Classes
● Les littéraux après :
@pgdejardin #moisdujs
const edit = (item, job) => ({ type: EDIT, payload: { item, job }});
function filter(name, field) { return { [name]: 'Title', [field]: field }}
@XebiaFr
ES2015 : Les Objets et Classes
● Les classes :
@pgdejardin #moisdujs
class XSlotGrid extends HTMLElement { constructor(template) { this.innerHTML = template; }
onDataChanged(slots) { ... }}
@XebiaFr
ES2015 : Les Objets et Classes
@pgdejardin #moisdujs
class TodoItem extends Component { static propTypes = { label: PropTypes.string.isRequired }; get completionTime() { return this.state; } set completionTime(value) { this.setState(value); } cleanUp() { super.cleanUp(); this.state = getInitialState(); }}
@XebiaFr
Destructuration
@pgdejardin #moisdujs
const obj = {name: 'ES2015', date: new Date('2015/06/14')}; const {name, date} = obj; // name == ES2015, date == new Date('2015/06/14') const [x, y] = ['ES2015', 'Typescript']; // x == ES2015, y == Typescript
const {filters: {values}} = this.props;
@XebiaFr
Default
@pgdejardin #moisdujs
function f(x, y=12) { // y is 12 if not passed (or passed as undefined) return x + y;}
f(3) == 15;
@XebiaFr
For...of
@pgdejardin #moisdujs
for (var n of fibonacci) { // truncate the sequence at 1000 if (n > 1000) break; console.log(n);}
@XebiaFr
Rest
@pgdejardin #moisdujs
function sum(...numbers) { let result = 0; for (let num of numbers) { result += num; } return result;}
console.log(sum(1)); // 1console.log(sum(1, 2, 3, 4, 5)); // 15
@XebiaFr
Spread
@pgdejardin #moisdujs
function sum2(x, y, z) { return x + y + z;}
console.log(sum2(...[1,2,3])); // 6console.log(sum2([1, 2], 3)); // 6
@XebiaFr
Template string
@pgdejardin #moisdujs
const msg = `This is a pretty little template string.`;
const notLegalMsg = `In ES5 this is not legal.`;
const name = 'Bob';const time = 'today';const welcomeMsg = `Hello ${name}, how are you ${time}?`;
const unescaped = String.raw`In ES5 "\n" is a line-feed.`;
@XebiaFr
Littéraux étendus
● Unicode● Octal et binaire
@pgdejardin #moisdujs
" ".length == 2; // same as ES5.1" ".match(/./u)[0].length == 2; // new RegExp behaviour, opt-in ‘u’"\u{20BB7}" == " " == "\uD842\uDFB7"; // new form" ".codePointAt(0) == 0x20BB7; // new String ops
0b111110111 === 503 // true
0o767 === 503 // true
@XebiaFr
Les modules : Exports
@pgdejardin #moisdujs
import _ from 'lodash';
export default function padLeft(str, num) { return _.padLeft(str, num);}export function concat(a, b) { return `${a}${b}`;}export const variable = 'a value';export {concat as concatString, variable};
@XebiaFr
Les modules : Imports
@pgdejardin #moisdujs
import React, { Component, PropTypes } from 'react';import * as _ from 'lodash';import padLeft from './StringUtil';import {concat} from './StringUtil';
const result1 = padLeft('Hello', 2);const result2 = concat('Hello', ' World');
@XebiaFr
L'asynchronisme : Promesses
● Garanties d'appel unique et exclusif● Capture des exceptions / erreurs● Composabilité
@pgdejardin #moisdujs
SlotsService.getSlots() .then(slots => SlotsService.transformSlots(slots)) .then(newSlots => _.map(newSlots, 'name')) .catch(err => logger.error(err));
@XebiaFr
L'asynchronisme : Async/Await (ES2017)
@pgdejardin #moisdujs
async getSlotsAsync() { try { const slots = await SlotsService.getSlots(); const transformedSlots = await SlotsService.transformSlots(slots); return _.map(transformedSlots, 'name'); } catch (err) { logger.error(err) }}
@XebiaFr
L'asynchronisme : Async/Await
● Ne remplace pas les Promesses● Mais plus s'ajoute en complément pour plus de clarté● Code asynchrone non bloquant mais écrit comme du synchrone● Le futur !!! (ES2017 Stage-3)
@pgdejardin #moisdujs
@XebiaFr
● Fait par Microsoft en 2012● Développé par Anders Heljsberg (Delphi, Turbo Pascal, C#)● Open source sous License Apache 2● sur-ensemble d'ES2015/2016● se transpile en javascript
Typescript !
@pgdejardin #moisdujs
@XebiaFr
Typescript : Les types
@pgdejardin #moisdujs
const title:string = 'Mois du JS';const nbSlots:number = 3;
let slotName:string = 'ES2015';slotName = 3; // Error number is not a stringslotName.any = 3; // Error
const slots:Array<string> = ['ES2015', 'Tests', 'ESLint'];
@XebiaFr
Typescript : Les classes
@pgdejardin #moisdujs
class Slot { title:string; date:Date; constructor(title:string, date:Date) { this.title = title; this.date = date; }}const tsSlot:Slot = new Slot('Typescript', new Date('2016/06/14'));console.log(tsSlot.title);
@XebiaFr
Typescript : Les enums
@pgdejardin #moisdujs
enum Week { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday}
console.log(Week.Monday !== Week.Friday); // trueconsole.log(Week.Monday == 0); // true and compile
@XebiaFr
Typescript : Les interfaces
@pgdejardin #moisdujs
interface Canid { name:string bark():string}class Dog extends Animal implements Canid { name:string; bark():string { return 'woaf'; }}
@XebiaFr
Typescript : Les interfaces
@pgdejardin #moisdujs
interface Canid { name:string bark():string}class Dog extends Animal implements Canid { name:string; bark():string { return 'woaf'; }}
@XebiaFr
Typescript : Le 'any' ou Typage graduel
@pgdejardin #moisdujs
let anyVariable:any = 'a variable';anyVariable = 1;
let husky:Husky = new Husky('Toto');let pug:Pug = new Pug('Titi');pug = husky; // Error properties from Pug missing in Husky
let jokerDog:any = husky;pug = jokerDog; // OK
@XebiaFr
Typescript : Les soucis...
● Transpilation (Pour le moment ca n'en est pas un car obligé de transpiler pour ES6)
● Vitesse de compilation sur les gros projets● Les fichiers de définitions
@pgdejardin #moisdujs
@XebiaFr
Typescript : Conclusion
● Utilisable avec du javascript (migration progressive)● Auto-completion avec IDE plus forte qu'en javascript● ES2015-2016 !!!● Refactoring plus simple qu'en javascript● Simple à apprendre
@pgdejardin #moisdujs
@XebiaFr
Merci !
Questions ?
@pgdejardin #moisdujs