Le matériel, dont nous présentons la traduction à votre attention, est consacré à l'étude des fonctionnalités des littéraux d'objets en JavaScript, en particulier les innovations apparues dans les versions récentes de la norme ECMAScript.
JavaScript a une capacité puissante et pratique pour créer des objets à l'aide de littéraux d'objets. La norme ES2015 (ES6) simplifie le travail avec les objets lors de la création d'applications pour les navigateurs modernes (sauf IE) et pour la plateforme Node.js.

Les bases
La création d'objets dans certains langages peut être gourmande en ressources, ce qui signifie à la fois le temps de travail du programmeur et les ressources informatiques des systèmes. En particulier, nous parlons du fait qu'avant de créer des objets, vous devez décrire les classes (par exemple, en utilisant le mot
class
clé
class
). En JavaScript, les objets peuvent être créés très rapidement et simplement, sans aucune étape préalable. Prenons un exemple:
// ES5 var myObject = { prop1: 'hello', prop2: 'world', output: function() { console.log(this.prop1 + ' ' + this.prop2); } }; myObject.output(); // hello world
En programmation, des objets «jetables» sont souvent utilisés. Ils stockent des paramètres et d'autres données, ils sont utilisés comme paramètres de fonctions, comme valeurs renvoyées par des fonctions et dans d'autres situations. Dans de tels cas, les littéraux d'objets JavaScript s'avèrent très utiles et ES6 étend leurs capacités.
Initialisation d'objets à partir de variables
Les propriétés des objets sont souvent créées à partir de variables en leur attribuant les mêmes noms qui sont déjà attribués à ces variables. Par exemple:
Dans ES6, vous n'avez plus besoin de répéter les noms de variables:
Cette technique peut être utile pour les objets renvoyés lors de l'utilisation du modèle de
module de révélation , qui vous permet de créer des espaces de noms pour divers fragments de code afin d'éviter les conflits de noms. Par exemple:
// ES6 const lib = (() => { function sum(a, b) { return a + b; } function mult(a, b) { return a * b; } return { sum, mult }; }()); console.log( lib.sum(2, 3) ); // 5 console.log( lib.mult(2, 3) ); // 6
Vous avez peut-être vu comment cette technique est utilisée dans les modules ES6:
// lib.js function sum(a, b) { return a + b; } function mult(a, b) { return a * b; } export { sum, mult };
Syntaxe abrégée pour déclarer des méthodes d'objet
Lors de la déclaration des méthodes d'objet dans ES5, vous devez utiliser le mot clé de
function
:
// ES5 var lib = { sum: function(a, b) { return a + b; }, mult: function(a, b) { return a * b; } }; console.log( lib.sum(2, 3) ); // 5 console.log( lib.mult(2, 3) ); // 6
Maintenant, dans ES6, vous ne pouvez plus faire cela. Ici, la méthode de déclaration de méthode abrégée suivante est autorisée:
// ES6 const lib = { sum(a, b) { return a + b; }, mult(a, b) { return a * b; } }; console.log( lib.sum(2, 3) ); // 5 console.log( lib.mult(2, 3) ); // 6
Il convient de noter que les fonctions fléchées ES6 (
=>
) ne peuvent pas être utilisées ici, car les méthodes doivent avoir des noms. Cependant, les fonctions fléchées peuvent être utilisées si vous attribuez explicitement des noms aux méthodes (comme dans ES5). Par exemple:
// ES6 const lib = { sum: (a, b) => a + b, mult: (a, b) => a * b }; console.log( lib.sum(2, 3) ); // 5 console.log( lib.mult(2, 3) ); // 6
Touches dynamiques
Dans ES5, vous ne pouviez pas utiliser de variables comme noms de clé, bien que la clé dont le nom est donné à la variable puisse être ajoutée après la création de l'objet. Par exemple:
// ES5 var key1 = 'one', obj = { two: 2, three: 3 }; obj[key1] = 1; // obj.one = 1, obj.two = 2, obj.three = 3
Dans ES6, les clés peuvent être attribuées dynamiquement en plaçant une expression de nom entre crochets (
[]
). Par exemple:
// ES6 const key1 = 'one', obj = { [key1]: 1, two: 2, three: 3 }; // obj.one = 1, obj.two = 2, obj.three = 3
Pour créer une clé, vous pouvez utiliser n'importe quelle expression:
// ES6 const i = 1, obj = { ['i' + i]: i }; console.log(obj.i1); // 1
Les clés dynamiques peuvent être utilisées pour les méthodes et les propriétés:
// ES6 const i = 2, obj = { ['mult' + i]: x => x * i }; console.log( obj.mult2(5) ); // 10
Une autre question est de savoir s'il faut créer des propriétés et des méthodes avec des noms générés dynamiquement. La lisibilité du code qui utilise cette technique peut être dégradée. Peut-être que si vous êtes confronté à des situations dans lesquelles les noms dynamiques semblent appropriés, il serait préférable de penser à utiliser des fonctions ou des classes d'usine pour créer des objets.
Restructuration
La déstructuration est l'extraction des propriétés des objets et leur affectation aux variables. Souvent pendant le développement d'application, vous devez extraire la valeur d'une propriété d'objet et l'écrire dans une variable. Dans ES5, vous deviez décrire cela comme suit, à l'aide des commandes d'accès aux propriétés:
// ES5 var myObject = { one: 'a', two: 'b', three: 'c' }; var one = myObject.one, // 'a' two = myObject.two, // 'b' three = myObject.three; // 'c'
ES6 prend en charge la déstructuration. Vous pouvez créer une variable avec le même nom qui porte la propriété correspondante de l'objet et procédez comme suit:
// ES6 const myObject = { one: 'a', two: 'b', three: 'c' }; const { one, two, three } = myObject; // one = 'a', two = 'b', three = 'c'
Les variables dans lesquelles se trouvent les valeurs des propriétés des objets peuvent en fait avoir des noms, mais si elles diffèrent des noms de propriétés, vous devez utiliser la construction
{ propertyName: newVariable }
:
// ES6 const myObject = { one: 'a', two: 'b', three: 'c' }; const { one: first, two: second, three: third } = myObject; // first = 'a', second = 'b', third = 'c'
Les objets avec une structure complexe, dans lesquels des tableaux et d'autres objets sont intégrés, peuvent également être utilisés dans des opérations d'affectation destructives:
// ES6 const meta = { title: 'Enhanced Object Literals', pageinfo: { url: 'https://www.sitepoint.com/', description: 'How to use object literals in ES2015 (ES6).', keywords: 'javascript, object, literal' } }; const { title : doc, pageinfo: { keywords: topic } } = meta; /* doc = 'Enhanced Object Literals' topic = 'javascript, object, literal' */
Au début, tout cela peut sembler compliqué, cependant, il n'est pas si difficile de le comprendre, l'essentiel est de se rappeler ce qui suit:
- Le côté droit de l'expression est la source de données - un tableau ou un objet qui stocke les données à récupérer.
- Le côté gauche de l'expression est le but de l'affectation destructrice - une structure qui décrit les variables auxquelles seront attribuées les valeurs extraites du tableau ou de l'objet.
Lorsque vous utilisez la déstructuration, vous pouvez rencontrer des difficultés. Ainsi, une expression ne peut pas être démarrée avec une accolade, car elle ressemblera alors à un bloc de code. Par exemple:
{ a, b, c } = myObject;
Cette conception est normalement perçue par le système lors de la déclaration des variables:
const = myObject;
Si les variables sont déjà déclarées, vous devez mettre l'expression entre parenthèses:
let a, b, c; ({ a, b, c } = myObject);
Par conséquent, lorsque vous traitez avec la déstructuration, vous devez faire attention au code et ne pas mélanger les variables déclarées et non déclarées.
La déstructuration est une technique qui peut être utile dans de nombreuses situations.
Paramètres de fonction par défaut
Si une fonction a besoin d'une longue liste d'arguments, il est généralement plus facile de lui passer un seul objet avec des paramètres. Par exemple:
prettyPrint( { title: 'Enhanced Object Literals', publisher: { name: 'SitePoint', url: 'https://www.sitepoint.com/' } } );
Dans ES5, il était nécessaire d'analyser les objets avec des paramètres afin, si ces objets n'ont pas ce dont ils ont besoin, d'affecter des valeurs par défaut aux paramètres correspondants:
// ES5, function prettyPrint(param) { param = param || {}; var pubTitle = param.title || 'No title', pubName = (param.publisher && param.publisher.name) || 'No publisher'; return pubTitle + ', ' + pubName; }
Dans ES6, tous les paramètres peuvent recevoir des valeurs par défaut:
// ES6 - function prettyPrint(param = {}) { ... }
Vous pouvez ensuite utiliser la déstructuration pour extraire des valeurs de l'objet et, si nécessaire, pour affecter des valeurs par défaut:
// ES6 function prettyPrint( { title: pubTitle = 'No title', publisher: { name: pubName = 'No publisher' } } = {} ) { return `${pubTitle}, ${pubName}`; }
Il convient de noter qu'un tel code peut être plus difficile à lire que plus traditionnel, bien que ce soit une question de préférences personnelles du programmeur.
Analyser les objets retournés par les fonctions
Les fonctions ne peuvent renvoyer qu'une seule valeur, mais cette valeur peut être un objet avec des centaines de propriétés ou de méthodes. Dans ES5, vous deviez d'abord obtenir l'objet renvoyé, puis vous pouviez en extraire les valeurs:
La restructuration simplifie ce processus. Maintenant, tout cela peut être fait sans avoir à enregistrer l'objet dans une variable distincte puis à l'analyser:
Vous avez peut-être vu quelque chose de similaire dans Node.js. Par exemple, si vous n'avez besoin que des
readFile()
et
writeFile()
du module
fs
, vous pouvez obtenir des liens vers celles-ci comme ceci:
// ES6 Node.js const { readFile, writeFile } = require('fs'); readFile('file.txt', (err, data) => { console.log(err || data); }); writeFile('new.txt', 'new content', err => { console.log(err || 'file written'); });
Syntaxe des paramètres restants et opérateur d'extension ES2018 (ES9)
= Dans ES2015, la syntaxe des paramètres restants et l'opérateur d'extension (les deux ressemblent à trois points,
…
) ont été utilisés uniquement lorsque vous travaillez avec des tableaux. Dans ES2018, des fonctionnalités similaires peuvent être utilisées pour travailler avec des objets:
const myObject = ; const = myObject;
Une approche similaire peut être utilisée pour transférer certaines valeurs vers une fonction:
function restParam({ a, ...x }) {
Veuillez noter que dans de telles situations, vous ne pouvez utiliser qu'une seule expression avec trois points à la fin de la liste. De plus, pour les objets imbriqués dans d'autres objets, cela ne fonctionne pas.
L'opérateur d'extension peut être utilisé à l'intérieur des objets:
const obj1 = , obj2 = ;
L'opérateur d'extension peut être utilisé pour cloner des objets (
obj2 = { ...obj1 };
), mais ici, il faut garder à l'esprit qu'avec cette approche, une copie superficielle de l'objet est effectuée. Si les propriétés des objets sont d'autres objets, le clone de l'objet fera référence aux mêmes objets imbriqués.
La syntaxe des paramètres restants et l'opérateur d'extension ne sont pas encore largement pris en charge. Actuellement, ils peuvent être utilisés dans les navigateurs Chrome et Firefox sans efforts supplémentaires et lors du développement pour la plate-forme Node.js version 8.6 et supérieure.
Résumé
Les littéraux d'objets ont toujours été une fonctionnalité JavaScript utile. Les innovations qui apparaissent en JavaScript depuis la norme ES2015 n'apportent pas de changements fondamentaux, mais elles font gagner du temps au programmeur et aident à écrire du code plus propre et concis.
Chers lecteurs! Quelles méthodes de création d'objets JS utilisez-vous le plus souvent?
