IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

ECMAScript 2015 (ES6) c'est le JavaScript d'aujourd'hui
Un billet de Daniel Hagnoul

Le , par danielhagnoul

0PARTAGES

Il est plus que temps de se documenter et d'apprendre à s'en servir !

Ce n'est pas parce qu'à votre travail les outils datent de l'âge des dinosaures que votre esprit doit y rester.

Documentation

Pour apprendre en français, il y a MDN

Mais pour approfondir le sujet ou avoir accès aux dernières nouveautés, il faut consulter les sources anglophones.

Pour débuter, je vous conseille : Getting started with ECMAScript 6

Puis de lire : Exploring ES6

ES2015 natif

Exemple, non exhaustif, de ce qui est déjà utilisable :








Test




Test du ES2015 natif (exemple non exhaustif)


Voir le code et le contenu de la console




Le code ci-dessous fonctionne dans les navigateurs dignes de ce nom, à savoir Edge et Chrome.


J'ai testé avec Edge 20.10240.16384.0 et Chrome 45.0.2454.46 beta-m (64-bit)


Firefox 40.0.2 se contente d'afficher "SyntaxError: let is a reserved identifier".


Ce navigateur est à la traîne depuis des mois, je le délaisse de plus en plus.


Pour les navigateurs totalement obsolètes (genre IE), il faut arrêter de croire au Père Noël.




<script>
"use strict";

const y = 5;
let x = 100;

{ // bloc de code

let x = 6;

// 6 * 5 = 30
console.log( x * y );
}

{
let x = 0.5;

// 0.5 * 5 = 2.5
console.log( x * y );
}

// 100 * 5 = 500
console.log( x * y );

// Impossible
// TypeError: Assignment to constant variable.
// y = 12;

{
// Array.from() facilite la manipulation des nodes

Array.from( document.querySelectorAll( 'p' ) ).forEach( ( node ) => { console.log( node.innerText ); } );

/*
* ( p ) => { console.log( p.innerText ); }
* signbifie : function( p ){ console.log( p.innerText ); }
*/

// variante avec for of

for ( let node of Array.from( document.querySelectorAll( 'p' ) ) ){
console.log( node.innerText );
}

}

{
// Array.findIndex() et Object.is() facilite la
// recherche d'un élément, même si cet élément est NaN

let myIndexOf = function( arr, elem ){
return arr.findIndex( x => Object.is( x, elem ) );
}

/*
* x => Object.is( x, elem )
* signifie : function( x ){ return Object.is( x, elem ); }
*/

let
arr = [ 0, NaN, 2 ],
pos = myIndexOf( arr, NaN );

// 1
console.log( pos );
}

{
// pour vos messages, n'utilisez plus "text" ou 'text' mais
// `text` (accent grave)

console.log( `Un texte qui se moque des ' et des ".` );

// on peut alors utiliser la forme template ${ ... } pour insérer
// la valeur d'une variable dans le texte

console.log( `y = ${ y } ne peut pas être modifié, c'est une constante !` );
}

{
// manipulation d'un objet
// filter() facilite le tri

let animals = [
{
"name" : "Waffles",
"type": "dog",
"age" : 12
},
{
"name" : "Fluffy",
"type" : "cat",
"age" : 14
},
{
"name" : "Spelunky",
"type" : "dog",
"age" : 4
},
{
"name" : "Hank",
"type" : "dog",
"age" : 11
}
];

let
oldDogNames = animals
.filter( ( x ) => x.age > 10 && x.type === "dog" )
.map( ( x ) => x.name );

// oldDogNames = [ "Waffles", "Hank" ].
console.log( oldDogNames );

let
totalDogYears = animals
.filter( ( x ) => x.type === "dog" )
.map( ( x ) => x.age )
.reduce( function( prev, cur ){
return ( prev + cur );
}, 0 );

// totalDogYears = 27 (Waffles 12 + Spelunky 4 + Hank 11)
console.log( totalDogYears );
}

{
// déclaration et construction d'un objet
// rappel : x (let) et y (const) sont déclarés au début du script
// et accessible dans tous les blocs de code.

let Obj = Object.assign( {}, { x, y, "bar" : true } );

// Obj = { "x" : 100, "y" : 5, "bar" : true }
console.log( JSON.stringify( Obj ) );

// 100
console.log( `Obj.x = ${ Obj.x }` );
}

{
// fonction asynchrone grâce aux promesses

let asyncFunc = function( ){

return new Promise( function( resolve, reject ){

if ( x < 100 ){
resolve( 15 );
} else {
reject( `Valeur incompatible, promesse non tenue` );
}

});
};

// utilisation

asyncFunc( )
.then( ( value ) => { console.log( "done", value ); } )
.catch( ( error ) => { console.log( "fail", error ); } );
}

{
// Map, création, remplissage et manipulation

let map = new Map([
[ false, 'no' ],
[ true, 'yes' ],
]);

map.set( "numéro", 123 );
map.set( "nom", "Hagnoul" );

for ( let key of map.keys() ){
console.log( key );
}

for ( let value of map.values() ){
console.log( value );
}

for ( let entry of map.entries() ){
console.log( entry[ 0 ], entry[ 1 ] );
}

console.log( map.size, map.has( "numéro" ), map.get( "nom" ) );

map.delete( true );

console.log( map.size, map.has( true ) );
}

{
// Set, création, remplissage et manipulation
// méthodes get(), set(), has(), delete() et propriété size comme pour Map

// les doublons sont écartés automatiquement
let set = new Set( [5, 1, 5, 7, 7, 5] );

for ( let value of set.values() ){
console.log( value );
}
}





ES2015 compilé en ES5

Les outils transformant du code ES2015 en ES5 sont nombreux.

Celui qui fait le plus de bruit, c'est Babel.

J'utilise exclusivement traceur.js dans le navigateur Chrome.

Exemple composé de deux fichiers JS et d'un fichier HTML.

Le fichier dvjhUtilities.js est un fichier contenant des fonctions utilitaires :

"use strict";

const
kIsoFormat = d3.time.format( "%Y-%m-%dT%H:%M:%S.%L%Z" ),
kModel = Symbol( 'ObjModel' ),
kGetType = function( Obj ){
return Object.prototype.toString.call( Obj ).match( /\s([a-zA-Z]+)/ )[ 1 ].toLowerCase();
},
kSetModel = function( Obj ){

if ( kGetType( Obj ) === "object" ){

Obj[ kModel ] = Object.create( Object.prototype );

Object.getOwnPropertyNames( Obj ).forEach( function( key ){

if ( key != kModel ) {

Object.defineProperty( Obj[ kModel ], key, {
"value" : kGetType( Obj[ key ] ),
"enumerable" : true
});
}
});

Object.getOwnPropertySymbols( Obj ).forEach( function( key ){

if ( key != kModel ) {

Object.defineProperty( Obj[ kModel ], key, {
"value" : kGetType( Obj[ key ] ),
"enumerable" : true
});
}
});

} else {
throw `Erreur dans kSetModel(), ${Obj} n'est pas un objet`;
}
},
kCreateDOMObject = function( domFragment, keys, boolChildren ){

let
Obj = Object.create( Object.prototype ),
nodes = [],
treeWalker = {},
bool = boolChildren || false;

if ( kGetType( domFragment ).slice( 0, 4 ) === "html" ) {

treeWalker = document.createTreeWalker(
domFragment,
NodeFilter.SHOW_ELEMENT,
{
"acceptNode" : function( node ){
if ( bool ) {
return NodeFilter.FILTER_ACCEPT;
} else if ( node.parentNode === domFragment ) {
return NodeFilter.FILTER_ACCEPT;
}

return NodeFilter.FILTER_SKIP;
}
},
false
);

while( treeWalker.nextNode() ){
nodes.push( treeWalker.currentNode );
}

nodes.forEach( function( item, i ){
let key = "dom_" + ( keys[ i ] ? keys[ i ] : i );

Object.defineProperty( Obj, key, {
"value" : item,
"enumerable" : true
});
});
} else {
alert( `L'objet créé est vide, car le paramètre domFragment ne contient pas un fragment du DOM` );
}

return Obj;
},
dvjhDate = class extends Date {
constructor( p ){
if ( p ) {
super( p );
} else {
super();
}

this.auteur = 'Daniel Hagnoul';
}
toString(){
return kIsoFormat( this );
}
};


Le fichier dvjhClass.js est exploité comme module ES2015 :

"use strict";

const
kFirstName = new WeakMap(),
kLastName = new WeakMap(),
kFirstNameType = 'string',
kLastNameType = 'string',
kSetPerson = function( obj, first, last ){

if ( kGetType( first ) === kFirstNameType && kGetType( last ) === kLastNameType ){

kFirstName.set( obj, first );
kLastName.set( obj, last );

} else {
throw `Type des paramètres incompatibles.
first : ${ kFirstNameType } attendu,
last : ${ kLastNameType } attendu`;
}

return obj;
},
kPays = Symbol( 'Pays' ),
kPaysType = 'string',
kSetPays = function( obj, value ){

if ( kGetType( value ) === kPaysType ){
obj[ kPays ] = value;

} else {
throw `Type des paramètres incompatibles.
pays : ${ kPaysType } attendu`;
}

return obj;
};

export const Person = class {
constructor( first, last ){
kSetPerson( this, first, last );
}
get firstName( ){
return kFirstName.get( this );
}
get lastName( ){
return kLastName.get( this );
}
fullName( ){
return kFirstName.get( this ) + " " + kLastName.get( this );
}
};

export const Employee = class extends Person {
constructor( prenom, nom, pays ){
super( prenom, nom );
kSetPays( this, pays );
}
get pays( ){
return this[ kPays ];
}
set pays( value ){
kSetPays( this, pays );
}
};







Test




Titre









Vous avez lu gratuitement 103 articles depuis plus d'un an.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.

Une erreur dans cette actualité ? Signalez-nous-la !