JavaScript

ES6

Affectations déstructurées

var httpOptions = { timeout: 2000, isCache: true };
// ES5 :
var httpTimeout = httpOptions.timeout;
var httpCache = httpOptions.isCache;
// ES6 :
const { timeout: httpTimeout, isCache: httpCache } = httpOptions;
// or
const { timeout, isCache } = httpOptions;
// you now have a variable named 'timeout' and one named 'isCache' with correct values

avec des objets imbriqués :

const httpOptions = { timeout: 2000, cache: { age: 2 } };
// later
const { cache: { age } } = httpOptions;
// you now have a variable named 'age' with value 2

avec des tableaux :

const timeouts = [1000, 2000, 3000];
// later
const [shortTimeout, mediumTimeout] = timeouts;
// you now have a variable named 'shortTimeout' with value 1000
// and a variable named 'mediumTimeout' with value 2000

avec des fonctions :

function randomPonyInRace() {
	const pony = { name: 'Rainbow Dash' };
	const position = 2;
	// ...
	return { pony, position };
}
const { position, pony } = randomPonyInRace();
// ou
const { pony } = randomPonyInRace();

Paramètres optionnels et valeurs par défaut

function getPonies(size, page) {
	size = size || 10;
	page = page || 1;
	// ...
	server.get(size, page);
}

ou

function getPonies(size = 10, page = 1) {
	// ...
	server.get(size, page);
}

avec appel de fonction :

function getPonies(size = defaultSize(), page = size - 1) {
// if page is not provided, it will be set to the value
// of the size parameter minus one.
// ...
server.get(size, page);
}

avec une affectation déstructurée :

const { timeout = 1000 } = httpOptions;

Rest Operator

function addPonies(...ponies) {
	for (let pony of ponies) {
	poniesInRace.push(pony);
	}
}
const [winner, ...losers] = poniesInRace;
// assuming 'poniesInRace' is an array containing several ponies
// 'winner' will have the first pony,
// and 'losers' will be an array of the other ones
const ponyPrices = [12, 3, 4];
const minPrice = Math.min(...ponyPrices);

Classes

class Pony {
	get color() {
		console.log('get color');
		return this._color;
	}
	set color(newColor) {
		console.log(`set color ${newColor}`);
		this._color = newColor;
	}
	static defaultSpeed() {
		return 10;
	}
}
const pony = new Pony();
pony.color = 'red';
// 'set color red'
console.log(pony.color);
// 'get color'  (red')

Héritage

class Animal {
	speed() {
		return 10;
	}
}
class Pony extends Animal {
	speed() {
		return super.speed() + 10;
	}
}
const pony = new Pony();
console.log(pony.speed()); // 20, as Pony overrides the parent method
class Animal {
	constructor(speed) {
		this.speed = speed;
	}
}
class Pony extends Animal {
	constructor(speed, color) {
		super(speed);
		this.color = color;
	}
}
const pony = new Pony(20, 'blue');
console.log(pony.speed); // 20

Promises

getUser(login)
	.then(function (user) {
		return getRights(user);
	})
	.then(function (rights) {
		updateMenu(rights);
	})

Une promise a trois états :

  • pending (« en cours ») : quand la promise n’est pas réalisée
    par exemple quand l’appel serveur n’est pas encore terminé.
  • fulfilled (« réalisée ») : quand la promise s’est réalisée avec succès
    par exemple quand l’appel HTTP serveur a retourné un status 200-OK.
  • rejected (« rejetée ») : quand la promise a échoué
    par exemple si l’appel HTTP serveur a retourné un status 404-NotFound.
const getUser = function (login) {
	return new Promise(function (resolve, reject) {
		// async stuff, like fetching users from server, returning a response
		if (response.status === 200) {
			resolve(response.data);
		} else {
			reject('No user');
		}
	});
};

Une gestion d’erreur par promise :

getUser(login)
	.then(function (user) {
		return getRights(user);
	}, function (error) {
		console.log(error); // will be called if getUser fails
		return Promise.reject(error);
	})
	.then(function (rights) {
		return updateMenu(rights);
	}, function (error) {
		console.log(error); // will be called if getRights fails
		return Promise.reject(error);
	})

Une gestion d’erreur globale pour toute la chaîne :

getUser(login)
	.then(function (user) {
		return getRights(user);
	})
	.then(function (rights) {
		return updateMenu(rights);
	})
	.catch(function (error) {
		console.log(error); // will be called if getUser or getRights fails
	})

arrow functions

getUser(login)
	// ES5
	.then(function (user) {
		return getRights(user); // getRights is returning a promise
	})
	.then(function (rights) {
		return updateMenu(rights);
	})
	// ES6
	.then(user => getRights(user))
	.then(rights => updateMenu(rights))

Le return est implicite s’il n’y a pas de bloc : pas besoin d’écrire user ⇒ return getRights(user).

les arrow functions ont une particularité bien agréable que n’ont pas les fonctions normales : le this reste attaché lexicalement, ce qui signifie que ces arrow functions n’ont pas un nouveau this comme les fonctions normales :

var maxFinder = {
	max: 0,
	find: function (numbers) {
		// ES5
		numbers.forEach(
		function (element) {
			if (element > this.max) {
				this.max = element;
			}
		}, this); // on doit passer le this en second paramètre
		// ES6
		numbers.forEach(element => {
			if (element > this.max) {
				this.max = element;
			}
		});
	}
};
maxFinder.find([2, 3, 4]);
// log the result
console.log(maxFinder.max);

Collections

Map

const cedric = { id: 1, name: 'Cedric' };
const users = new Map();
users.set(cedric.id, cedric); // adds a user
console.log(users.has(cedric.id)); // true
console.log(users.size); // 1
users.delete(cedric.id); // removes the user

Set

const cedric = { id: 1, name: 'Cedric' };
const users = new Set();
users.add(cedric); // adds a user
console.log(users.has(cedric)); // true
console.log(users.size); // 1
users.delete(cedric); // removes the user

for…of

for (let user of users) {
	console.log(user.name);
}

Template de string

// ES5
const fullname = 'Miss ' + firstname + ' ' + lastname;
// ES6
const fullname = `Miss ${firstname} ${lastname}`;

Modules

Dans races_service.js :

export function bet(race, pony) { ... }
export function start(race) { ... }

Dans un autre fichier :

import { bet, start } from './races_service';
// later
bet(race, pony1);
start(race);
// import avec alias
import { start as startRace } from './races_service';
// tout importer
import * as racesService from './races_service';
// default :
// pony.js
export default class Pony {}
// races_service.js
import Pony from './pony';

Liens