Une présentation de Christophe Porteneuve à Paris Web 2015
var christophe = {
age: 37.90622861054072,
city: 'Paris',
company: 'Delicious Insights',
trainings: ['JS Total', 'Node.js', 'Git Total'],
webSince: 1995,
claimsToFame: [
'Prototype.js',
'Ruby On Rails',
'Bien Développer pour le Web 2.0',
'Prototype and Script.aculo.us',
'Paris Web'
]
};
Parce que
Transpile ES6+1 (ES6, ES7…) en ES5
Du coup, si tu as ES5, tu peux y aller
En pratique : IE9+, tous navigateurs modernes, Node.js
Intégré avec l’univers
Plus facile
Plus puissant
Plus fiable
Plus performant
Parce que juste sortir des exemples Toto / Tutu, ça empêche de vraiment intérioriser le potentiel du bestiau.
Véritable codebase : l’exemple TodoMVC de Redux
Quelques démos isolées lorsqu’on n’avait pas d’exemple adapté dans cette codebase.
On ne verra pas tout : certains trucs sont anecdotiques ou très, très expérimentaux. Mais ça devrait bien couvrir le truc.
function editTodo(id, text) {
return { type: types.EDIT_TODO, id, text };
}
FILTER_TITLES = {
[SHOW_ALL]: 'All',
[SHOW_ACTIVE]: 'Active',
[SHOW_COMPLETED]: 'Completed'
};
class TodoItem extends Component {
constructor(props, context) {
super(props, context);
this.state = {
editing: false
};
}
handleDoubleClick() {
this.setState({ editing: true });
}
…
}
const { activeCount } = this.props;
…
const { filter: selectedFilter, onShow } = this.props;
const [, filters] = output.props.children;
…
const [,, clear] = output.props.children;
var { op: a, lhs: { op: b }, rhs: c } = getASTNode();
function winners(first, runnerUp, ...others) {
console.log(first, runnerUp, others);
}
winners('alice', 'bob', 'claire', 'david')
// => 'alice', 'bob', ['claire', 'david']
var arr1 = ['one', 'two'], arr2 = ['three', 'four'];
arr1.push(...arr2) // => 4
arr1 // => ['one', 'two', 'three', 'four']
var defaults = { first: 'John', last: 'Doe', age: 42 };
var trainer = { last: 'Smith', age: 35 };
trainer = { ...defaults, ...trainer, age: 36 }
// => { first: 'John', last: 'Smith', age: 36 }
return [{ id: …, completed: …, text: … }, ...state];
<TodoItem key={todo.id} todo={todo} {...actions} />
function todos(state = initialState, action) {
…
}
var [first, second = 'foo'] = ['yo'];
// second === 'foo'
var person = { first: 'Louis', sex: 'M', age: 36 };
var { first, last = 'Doe', age = 42 } = person;
// first === 'Louis', last === 'Doe', age === 36
var person = { first: 'Thomas', last: 'Anderson', age: 25, nickname: 'Neo' };
// Interpolation de JS quelconque
console.log(`${person.first} aka ${person.nickname}`)
// => 'Thomas aka Neo'
// Multi-ligne !
var markup = `<li>
${person.first} ${person.last}, age ${person.age}
</li>`;
// Tagged template strings
function html(statics, ...exprs) {
return statics.reduce(function(acc, text, index) {
return acc + text + (exprs[index] || '').replace(/</g, '<');
}, '').join('');
}
var user = '<script>', comment = '<bgsound>';
html`<li>${user}: <blockquote>${comment}</blockquote></li>`
// => '<li><script>: <blockquote><bgsound></blockquote></li>'
this
lexical
onSave={(text) => this.handleSave(todo.id, text)} />
TODO_FILTERS = {
[SHOW_ALL]: () => true,
[SHOW_ACTIVE]: todo => !todo.completed,
[SHOW_COMPLETED]: todo => todo.completed
};
…
atLeastOneCompleted = this.props.todos.some(todo => todo.completed);
let
& const
const { activeCount } = this.props;
…
const { filter: selectedFilter, onShow } = this.props;
const ADD_TODO = 'ADD_TODO';
const DELETE_TODO = 'DELETE_TODO';
const EDIT_TODO = 'EDIT_TODO';
for (let index = 0; index < 10; ++index)
setTimeout(() => console.log(index), 10);
// => Effectivement de 0 à 9, pas 10 x 10, malgré l’asynchrone
0o52 // => 42
0b101010 // => 42
import * as types from '../constants/ActionTypes';
export function addTodo(text) {
return { type: types.ADD_TODO, text };
}
import React, { PropTypes, Component } from 'react';
import classnames from 'classnames';
import { SHOW_ALL, SHOW_COMPLETED, SHOW_ACTIVE } from '../constants/TodoFilters';
…
export default Footer;
export const ADD_TODO = 'ADD_TODO';
export const DELETE_TODO = 'DELETE_TODO';
export const EDIT_TODO = 'EDIT_TODO';
caches.match('/data.json').then(function(response) {
if (!response) throw Error("No data");
return response.json();
}).then(function(data) {
// don't overwrite newer network data
if (!networkDataReceived) {
updatePage(data);
}
}).catch(function() {
// we didn't get cached data, the network is our last hope:
return networkUpdate;
}).catch(showErrorMessage).then(stopSpinner);
Super manière de les apprivoiser : Promisees
var Promise = require("bluebird");
var R = require("ramda");
async function forecastCities()
{
var forecast = require("notebook")("tonic/forecast/1.0.0");
var promises = R.map(forecast.threeDay, arguments);
return R.zipObj(arguments, await Promise.map(promises, R.identity));
}
await forecastCities("New York", "San Francisco");
const Promise = require("bluebird");
const R = require("ramda");
await forecastCities("New York", "San Francisco");
async function forecastCities()
{
var forecast = require("notebook")("tonic/forecast/1.0.0");
var promises = R.map(forecast.threeDay, arguments);
return R.zipObj(arguments, await Promise.map(promises, R.identity));
}
let results = [
for (c of customers)
if (c.city == "Seattle")
{ name: c.name, age: c.age }
];
Pour comparaison, en CoffeeScript :
results = ({ name: c.name, age: c.age }
for c in customers when c.city is "Seattle")
class Meal {
@readonly
entree = 'Steak'
@memoized('5 minutes')
fullRun() {
// …
}
}
function safeObj(obj) {
return new Proxy(obj, {
get(target, propKey, receiver) {
if (!(propKey in target)) {
throw new ReferenceError('Unknown property: ' + propKey);
}
return Reflect.get(target, propKey, receiver);
}
});
}
var o = safeObj({ first: 'Christopher', last: 'Colombus' });
o.frist // => ReferenceError: Unknown property: frist
On fait des super formations de ouf sur
Git,
JavaScript et le dev web front et
Node.js.
Et ce qui est encore plus cool, c’est que pour l’auditoire Paris Web, c’est −15% sur toutes les sessions jusqu’à fin janvier, rien qu’avec votre n° d’inscription PW.
Christophe Porteneuve
Retrouvez les slides sur bit.ly/es6maintenant