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

Le , par danielhagnoul, Rédacteur
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 :
Code HTML : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
<!DOCTYPE html> 
<html lang="fr" dir="ltr"> 
<head> 
  <meta http-equiv="cache-control" content="public, max-age=60"> 
  <meta charset="utf-8"> 
  <meta name="viewport" content="initial-scale=1.0"> 
  <meta name="author" content="Daniel Hagnoul"> 
  <title>Test</title> 
  <style> 
  
  </style> 
</head> 
<body> 
  
  <h1>Test du ES2015 natif (exemple non exhaustif)</h1> 
  <h2>Voir le code et le contenu de la console</h2> 
  
  <div> 
    <p>Le code ci-dessous fonctionne dans les navigateurs dignes de ce nom, à savoir Edge et Chrome.</p> 
    <p>J'ai testé avec Edge 20.10240.16384.0 et Chrome 45.0.2454.46 beta-m (64-bit)</p> 
    <p>Firefox 40.0.2 se contente d'afficher "SyntaxError: let is a reserved identifier".</p> 
    <p>Ce navigateur est à la traîne depuis des mois, je le délaisse de plus en plus.</p> 
    <p>Pour les navigateurs totalement obsolètes (genre IE), il faut arrêter de croire au Père Noël.</p> 
  </div> 
  
  <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 ); 
      } 
    } 
  
  </script> 
</body> 
</html>

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 :
Code JavaScript : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
"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 :
Code JavaScript : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
"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 ); 
    } 
};
Code HTML : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<head> 
  <meta http-equiv="cache-control" content="public, max-age=60"> 
  <meta charset="utf-8"> 
  <meta name="viewport" content="initial-scale=1.0"> 
  <meta name="author" content="Daniel Hagnoul"> 
  <title>Test</title> 
  <style> 
     
    h1 { color: rgb( 202, 26, 84 ); } 
     
  </style> 
</head> 
<body> 
  
  <h1>Titre</h1> 
  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> 
  <script src="https://google.github.io/traceur-compiler/bin/traceur.js"></script> 
  <script src="https://google.github.io/traceur-compiler/src/bootstrap.js"></script> 
  <script src="dvjhUtilities.js"></script> 
  <script type="module"> 
    // script type module indique qu'il s'agit d'un fichier exploité par traceur.js 
  
    // on importe les fonctions exportables du module 
  
    import { Person, Employee } from 'dvjhClass.js'; 
  
    // construction de l'objet Moi à partir de la class Employee 
  
    let Moi = new Employee( "Daniel", "Hagnoul", "Belgique" ); 
  
    // on applique une fonction utilitaire sur l'objet Moi 
  
    kSetModel( Moi ); 
    console.log( Moi ); 
  
    console.log( Moi.firstName, Moi.lastName, Moi.pays ); 
  
    // fonction utilitaire, accessible 
    console.log( new dvjhDate() ); 
  
    // appel d'une fonction du module non exportée, donc inacessible 
    // provoque une erreur ! 
    // ReferenceError: kSetPerson is not defined 
    // console.log( kSetPerson( {}, "Jean", "Dupond" ) ); 
  </script> 
</body> 
</html>


Vous avez aimé cette actualité ? Alors partagez-la avec vos amis en cliquant sur les boutons ci-dessous :
Offres d'emploi IT
Architecte Sécurité H/F
Safran - Ile de France - Éragny (95610)
Ingénieur Développeur logiciel H/F
Safran - Ile de France - Massy (91300)
Ingénieur Développement logiciel H/F
Safran - Ile de France - Massy (91300)

Voir plus d'offres Voir la carte des offres IT
Responsable bénévole de la rubrique JavaScript : Xavier Lecomte -