Une présentation de Christophe Porteneuve à Blend Web Mix 2015
var christophe = {
age: 37.98015058179329,
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
préservé
<TodoTextInput text={todo.text}
editing={this.state.editing}
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.
Christophe Porteneuve
Retrouvez les slides sur bit.ly/deep-dive-es6
Plein de bonnes ressources pour apprendre ES6 et l’explorer