Innovations JavaScript: résultats de Google I / O 2019. Partie 2

Aujourd'hui, nous publions la deuxiÚme partie de la traduction des innovations JavaScript. Nous parlons ici de séparateurs de chiffres de nombres, de BigInt-nombres, de travailler avec des tableaux et des objets, de globalThis , de trier, de l'API d'internationalisation et de promesses.



→ La premiùre partie

Séparateurs de nombres


Les nombres longs trouvĂ©s dans les programmes sont difficiles Ă  lire. Par exemple, 1000000000 correspond Ă  un milliard de dĂ©cimales. Mais en un coup d’Ɠil, c’est difficile Ă  comprendre. Par consĂ©quent, si le lecteur du programme rencontre quelque chose de similaire - pour le percevoir correctement, il devra soigneusement considĂ©rer les zĂ©ros.

Dans le JavaScript moderne, vous pouvez utiliser le séparateur de chiffres - un trait de soulignement ( _ ), dont l'utilisation améliore la lisibilité des nombres longs. Voici à quoi ressemblent les nombres écrits à l'aide d'un délimiteur dans le code:

 var billion = 1_000_000_000; console.log( billion ); // 1000000000 

Les sĂ©parateurs peuvent ĂȘtre utilisĂ©s pour diviser arbitrairement des nombres en fragments. JavaScript, lorsqu'il s'agit de nombres, ignore simplement les sĂ©parateurs. Ils peuvent ĂȘtre utilisĂ©s lors de l'Ă©criture de n'importe quel nombre: entiers, virgule flottante, binaire, hexadĂ©cimal, octal.

 console.log( 1_000_000_000.11 ); // 1000000000.11 console.log( 1_000_000_000.1_012 ); // 1000000000.1012 console.log( 0xFF_00_FF ); // 16711935 console.log( 0b1001_0011 ); // 147 console.log( 0o11_17 ); // 591 

→ Support



Type de données Bigint


Les nombres en JavaScript sont créés à l'aide de la fonction constructeur Number .

La valeur maximale qui peut ĂȘtre reprĂ©sentĂ©e en toute sĂ©curitĂ© Ă  l'aide du type de donnĂ©es Number est (2⁔³ - 1), c'est-Ă -dire 9007199254740991. Vous pouvez voir ce nombre Ă  l'aide de la construction Number.MAX_SAFE_INTEGER .

Veuillez noter que lorsqu'un littéral numérique est utilisé dans le code JS, JavaScript le traite, créant un objet basé sur celui-ci à l'aide du constructeur Number . Le prototype de cet objet contient des méthodes pour travailler avec des nombres. Cela se produit avec tous les types de données primitifs .

Que se passera-t-il si nous essayons d'ajouter quelque chose au numéro 9007199254740991?

 console.log( Number.MAX_SAFE_INTEGER ); // 9007199254740991 console.log( Number.MAX_SAFE_INTEGER + 10 ); // 9007199254741000 

Le résultat de l'ajout de Number.MAX_SAFE_INTEGER et 10, la deuxiÚme sortie de console.log() , est incorrect. Cela est dû au fait que JS ne peut pas effectuer correctement les calculs avec des nombres supérieurs à la valeur de Number.MAX_SAFE_INTEGER . Vous pouvez résoudre ce problÚme en utilisant le bigint données bigint .

Le type bigint permet de représenter des entiers supérieurs à Number.MAX_SAFE_INTEGER . L'utilisation des valeurs BigInt est similaire à l'utilisation des valeurs de type Number . En particulier, le langage a la fonction BigInt() , avec laquelle vous pouvez créer les valeurs correspondantes, et le type de données bigint primitif bigint utilisé pour représenter les grands entiers.

 var large = BigInt( 9007199254740991 ); console.log( large ); // 9007199254740991n console.log( typeof large ); // bigint 

JavaScript ajoute n Ă  la fin des littĂ©raux BigInt. Pour nous, cela signifie que de tels littĂ©raux peuvent ĂȘtre Ă©crits en ajoutant n Ă  la fin des entiers.

Maintenant que nous avons des nombres BigInt à notre disposition, nous pouvons effectuer en toute sécurité des opérations mathématiques sur de grands nombres de type bigint .

 var large = 9007199254740991n; console.log( large + 10n ); // 9007199254741001n 

Un numĂ©ro de type n'est pas le mĂȘme qu'un numĂ©ro de type bigint . En particulier, nous parlons du fait que les nombres BigInt ne peuvent ĂȘtre que des entiers. Par consĂ©quent, il s'avĂšre que vous ne pouvez pas effectuer d'opĂ©rations arithmĂ©tiques utilisant les types bigint et number .

Il est à noter que la fonction BigInt() peut prendre différents nombres: décimal, binaire, hexadécimal, octal. A l'intérieur de cette fonction, ils seront convertis en nombres, pour la représentation desquels le systÚme numérique décimal est utilisé.

Le type bigint prend également en charge les séparateurs de bits:

 var large = 9_007_199_254_741_001n; console.log( large ); // 9007199254741001n 

→ Support



Nouvelles méthodes de tableau: .flat () et .flatMap ()


Ici, nous allons parler des nouvelles méthodes de prototype pour l'objet Array - les .flat() et .flatMap() .

▍ MĂ©thode .flat ()


Désormais, les objets de type Array ont une nouvelle méthode - .flat(n) . Il retourne un nouveau tableau, permettant récursivement d'élever les éléments des tableaux au niveau spécifié n . Par défaut, n est 1. Cette méthode peut passer n égal à Infinity , ce qui vous permet de convertir un tableau avec des tableaux imbriqués en un tableau unidimensionnel.

 var nums = [1, [2, [3, [4, 5]]]]; console.log( nums.flat() ); // [1, 2, [3, [4,5]]] console.log( nums.flat(2) ); // [1, 2, 3, [4,5]] console.log( nums.flat(Infinity) ); // [1, 2, 3, 4, 5] 

→ Support



▍ MĂ©thode .flatMap ()


Lors de la résolution de tùches quotidiennes, le programmeur peut parfois avoir besoin de traiter le tableau à l'aide de la méthode .map() avec sa transformation ultérieure en une structure plate. Par exemple, créez un tableau contenant les nombres et les carrés de ces nombres:

 var nums = [1, 2, 3]; var squares = nums.map( n => [ n, n*n ] ) console.log( squares ); // [[1,1],[2,4],[3,9]] console.log( squares.flat() ); // [1, 1, 2, 4, 3, 9] 

La solution Ă  ce problĂšme peut ĂȘtre simplifiĂ©e en utilisant la mĂ©thode .flatMap() . Il convertit les tableaux renvoyĂ©s par la fonction de rappel qui lui est passĂ©e, tout comme ils convertiraient leur mĂ©thode .flat() avec le paramĂštre n Ă©gal Ă  1.

 var nums = [1, 2, 3]; var makeSquare = n => [ n, n*n ]; console.log( nums.flatMap( makeSquare ) ); // [1, 1, 2, 4, 3, 9] 

→ Support



▍ Object.fromEntries (), mĂ©thode


Il : possible d'extraire des paires de type : d'un objet : peut ĂȘtre utilisĂ©e Ă  l'aide de l' Object mĂ©thode statique, qui renvoie un tableau, dont chaque Ă©lĂ©ment est un tableau contenant, comme premier Ă©lĂ©ment, une clĂ©, et comme second - une valeur.

 var obj = { x: 1, y: 2, z: 3 }; var objEntries = Object.entries( obj ); console.log( objEntries ); // [["x", 1],["y", 2],["z", 3]] 

Nous avons maintenant à notre disposition une méthode statique Object.fromEntries() , qui nous permet de reconvertir une structure similaire en objet.

 var entries = [["x", 1],["y", 2],["z", 3]]; var obj = Object.fromEntries( entries ); console.log( obj ); // {x: 1, y: 2, z: 3} 

La méthode entries() été utilisée pour faciliter le filtrage et le mappage des données stockées dans les objets. Le résultat est un tableau. Mais jusqu'à présent, la tùche de convertir un tel tableau en objet n'a pas eu de belle solution. C'est pour résoudre ce problÚme que vous pouvez utiliser la méthode Object.fromEntries() .

 var obj = { x: 1, y: 2, z: 3 }; // [["x", 1],["y", 2],["z", 3]] var objEntries = Object.entries( obj ); // [["x", 1],["z", 3]] var filtered = objEntries.filter( ( [key, value] ) => value % 2 !== 0 //  ,     ); console.log( Object.fromEntries( filtered ) ); // {x: 1, z: 3} 

Si la structure Map : data est utilisĂ©e pour stocker les paires : , les donnĂ©es qu'elle contient sont stockĂ©es dans l'ordre oĂč elles y ont Ă©tĂ© ajoutĂ©es. Dans le mĂȘme temps, la façon dont les donnĂ©es sont stockĂ©es ressemble au tableau renvoyĂ© par la mĂ©thode Object.entries() . La mĂ©thode Object.fromEntries() est Object.fromEntries() facile Ă  utiliser pour transformer des structures de donnĂ©es de Map en objets.

 var m = new Map([["x", 1],["y", 2],["z", 3]]); console.log( m ); // {"x" => 1, "y" => 2, "z" => 3} console.log( Object.fromEntries( m ) ); // {x: 1, y: 2, z: 3} 

→ Support



▍ Global property globalThis


Nous connaissons le this utilisé en JavaScript. Il n'a pas de valeur fixe. Au lieu de cela, la signification de this dépend du contexte dans lequel il est accédé. Dans n'importe quel environnement, le this pointe vers un objet global lorsqu'il est accessible à partir du contexte du plus haut niveau. Telle est la signification globale de this .

En JavaScript basé sur un navigateur, par exemple, la valeur globale pour this est l'objet window . Vous pouvez le vérifier en utilisant la construction console.log(this) au niveau supérieur du fichier JavaScript (dans le contexte le plus externe) ou dans la console JS du navigateur.


Accéder à cela dans la console du navigateur

La valeur globale de this dans Node.js pointe vers un objet global . À l'intĂ©rieur d'un travailleur Web, il pointe vers le travailleur lui-mĂȘme. Cependant, obtenir la valeur globale de this valeur n'est pas une tĂąche facile. Le fait est que vous ne pouvez en parler nulle part. Par exemple, si vous essayez de le faire dans le constructeur de la classe, il s'avĂšre que this pointe vers une instance de la classe correspondante.

Dans certains environnements, le this self peut ĂȘtre utilisĂ© pour accĂ©der Ă  la valeur globale de this . Ce mot-clĂ© joue le mĂȘme rĂŽle que les mĂ©canismes d'accĂšs Ă  cette valeur dans les navigateurs, dans Node.js et chez les travailleurs Web. En utilisant la connaissance de la façon dont la valeur globale de this est appelĂ©e dans diffĂ©rents environnements, vous pouvez crĂ©er une fonction qui renvoie cette valeur:

 const getGlobalThis = () => { if (typeof self !== 'undefined') return self; if (typeof window !== 'undefined') return window; if (typeof global !== 'undefined') return global; if (typeof this !== 'undefined') return this; throw new Error('Unable to locate global `this`'); }; var globalThis = getGlobalThis(); 

Devant nous est un polyfill primitif pour obtenir le global de this objet. En savoir plus à ce sujet ici . JavaScript a maintenant le mot-clé globalThis . Il fournit un moyen universel d'accéder à la valeur globale de this pour différents environnements et ne dépend pas de l'emplacement du programme à partir duquel il est accédé.

 var obj = { fn: function() {  console.log( 'this', this === obj ); // true  console.log( 'globalThis', globalThis === window ); // true } }; obj.fn(); 

→ Support



Tri stable


La norme ECMAScript n'offre pas d'algorithme de tri de tableau spécifique que les moteurs JavaScript doivent implémenter. Il décrit uniquement l'API utilisée pour le tri. Par conséquent, en utilisant différents moteurs JS, on peut rencontrer des différences dans les performances des opérations de tri et dans la stabilité (stabilité) des algorithmes de tri.

Maintenant, la norme exige que les tableaux de tri soient stables. Des dĂ©tails sur la stabilitĂ© du tri peuvent ĂȘtre trouvĂ©s ici . L'essence de cette caractĂ©ristique des algorithmes de tri est la suivante. L'algorithme est stable si le rĂ©sultat du tri, qui est un tableau modifiĂ©, contient des Ă©lĂ©ments avec les mĂȘmes valeurs qui n'ont pas Ă©tĂ© affectĂ©s par le tri dans le mĂȘme ordre dans lequel ils ont Ă©tĂ© placĂ©s dans le tableau d'origine. Prenons un exemple:

 var list = [  { name: 'Anna', age: 21 },  { name: 'Barbra', age: 25 },  { name: 'Zoe', age: 18 },  { name: 'Natasha', age: 25 } ]; //      age [  { name: 'Natasha', age: 25 }  { name: 'Barbra', age: 25 },  { name: 'Anna', age: 21 },  { name: 'Zoe', age: 18 }, ] 

Ici, le tableau de list contenant les objets est triĂ© par le champ d' age de ces objets. Dans le tableau de list , un objet avec la propriĂ©tĂ© name Ă©gale Ă  Barbra est situĂ© avant l'objet avec la propriĂ©tĂ© name Ă©gale Ă  Natasha . Étant donnĂ© que les valeurs d' age de ces objets sont Ă©gales, nous pouvons nous attendre Ă  ce que dans le tableau triĂ©, ces Ă©lĂ©ments conservent l'ordre de disposition prĂ©cĂ©dent les uns par rapport aux autres. Cependant, dans la pratique, cela n'Ă©tait pas prĂ©visible. La façon exacte dont le tableau triĂ© sera formĂ© dĂ©pend entiĂšrement du moteur JS utilisĂ©.

DĂ©sormais, tous les navigateurs modernes et Node.js utilisent un algorithme de tri stable, appelĂ© lors de l'accĂšs Ă  la mĂ©thode du tableau .sort() . Cela vous permet d'obtenir toujours, pour les mĂȘmes donnĂ©es, le mĂȘme rĂ©sultat:

 //    [  { name: 'Barbra', age: 25 },  { name: 'Natasha', age: 25 }  { name: 'Anna', age: 21 },  { name: 'Zoe', age: 18 }, ] 

Dans le passé, certains moteurs JS prenaient en charge le tri stable, mais uniquement pour les petits tableaux. Pour améliorer les performances lors du traitement de grands tableaux, ils pourraient utiliser des algorithmes plus rapides et sacrifier la stabilité du tri.

→ Support


  • Chrome: 70+
  • Noeud: 12+
  • Firefox: 62+

API d'internationalisation


L'API d'internationalisation est conçue pour organiser des comparaisons de chaßnes, pour formater des nombres, des dates et des heures, comme cela est habituel dans diverses normes régionales (locales). L'accÚs à cette API est organisé via l'objet Intl . Cet objet fournit des constructeurs pour créer des objets de tri et des objets qui mettent en forme des données. La liste des paramÚtres régionaux pris en charge par l'objet Intl se trouve ici .

▍Intl.RelativeTimeFormat ()


Dans de nombreuses applications, il est souvent nécessaire de sortir l'heure dans un format relatif. Cela peut ressembler à «il y a 5 minutes», «hier», «il y a 1 minute», etc. Si le matériel du site Web est traduit dans différentes langues, vous devez inclure toutes les combinaisons possibles de constructions relatives décrivant l'heure dans l'assemblage du site.

JS dispose désormais du constructeur Intl.RelativeTimeFormat(locale, config) , qui vous permet de créer des systÚmes de formatage de la date et de l'heure pour différents paramÚtres régionaux. En particulier, nous parlons d'objets qui ont une méthode .format(value, unit) , qui vous permet de générer différents horodatages relatifs. Cela ressemble à ceci:

 // español ( ) var rtfEspanol= new Intl.RelativeTimeFormat('es', {  numeric: 'auto' }); console.log( rtfEspanol.format( 5, 'day' ) ); // dentro de 5 días console.log( rtfEspanol.format( -5, 'day' ) ); // hace 5 días console.log( rtfEspanol.format( 15, 'minute' ) ); // dentro de 15 minutos 

→ Support



▍Intl.ListFormat ()


Le constructeur Intl.ListFormat permet de combiner des Ă©lĂ©ments de liste en utilisant les mots and ( ) et or ( ). Lors de la crĂ©ation de l'objet correspondant, le constructeur reçoit les paramĂštres rĂ©gionaux et l'objet avec les paramĂštres. Son paramĂštre de type peut ĂȘtre la conjunction , la disjunction et l' unit . Par exemple, si nous voulons combiner les Ă©lĂ©ments du [apples, mangoes, bananas] aide d'un objet conjonction, nous obtenons une chaĂźne de la forme apples, mangoes and bananas . Si nous utilisons un objet disjonction, nous obtenons une chaĂźne de la forme apples, mangoes or bananas .

L'objet créé par le constructeur Intl.ListFormat a une .format(list) qui combine des listes. Prenons un exemple:

 // español ( ) var lfEspanol = new Intl.ListFormat('es', {  type: 'disjunction' }); var list = [ 'manzanas', 'mangos', 'plåtanos' ]; console.log( lfEspanol.format( list ) ); // manzanas, mangos o plåtanos 

→ Support



▍Intl.Locale ()


Le concept de «norme régionale» est généralement bien plus que le simple nom d'une langue. Cela peut inclure le type de calendrier, des informations sur les cycles de temps utilisés et les noms des langues. Le constructeur Intl.Locale(localeId, config) utilisé pour créer des chaßnes de Intl.Locale(localeId, config) formatées en fonction de l'objet de config transmis.

Intl.Locale objet créé à l'aide d' Intl.Locale contient tous les paramÚtres régionaux spécifiés. Sa méthode .toString() produit une chaßne standard régionale formatée.

 const krLocale = new Intl.Locale( 'ko', {  script: 'Kore', region: 'KR',  hourCycle: 'h12', calendar: 'gregory' } ); console.log( krLocale.baseName ); // ko-Kore-KR console.log( krLocale.toString() ); // ko-Kore-KR-u-ca-gregory-hc-h12 

Ici, vous pouvez lire sur les identifiants et les balises locales dans Unicode.

→ Support



Promesses


En Promise.all() moment, JS a les mĂ©thodes statiques Promise.all() et Promise.race() . La Promise.all([...promises]) renvoie une promesse qui est rĂ©solue avec succĂšs une fois toutes les promesses passĂ©es Ă  la mĂ©thode en tant qu'argument rĂ©solues. Cette promesse est rejetĂ©e dans le cas oĂč au moins une des promesses qui lui sont transfĂ©rĂ©es est rejetĂ©e. La Promise.race([...promises]) renvoie une promesse, qui est rĂ©solue aprĂšs la rĂ©solution de toute promesse qui lui est transfĂ©rĂ©e, et est rejetĂ©e si au moins une de ces promesses est rejetĂ©e.

La communauté des développeurs JS cherchait désespérément une méthode statique, la promesse retournée qui serait résolue aprÚs que toutes les promesses qui lui seraient passées seraient terminées (autorisées ou rejetées). De plus, nous avions besoin d'une méthode similaire à race() , qui retournerait une promesse en attendant la résolution de toutes les promesses qui lui seraient passées.

▍ MĂ©thode Promise.allSettled ()


La méthode Promise.allSettled() accepte un tableau de promesses. La promesse retournée par lui est autorisée aprÚs que toutes les promesses ont été rejetées ou autorisées. Le résultat est que la promesse retournée par cette méthode n'a pas besoin d'un catch .

Le fait est que cette promesse est toujours rĂ©ussie. Le bloc then reçoit le status et la value de chaque promesse dans l'ordre oĂč ils apparaissent.

 var p1 = () => new Promise(  (resolve, reject) => setTimeout( () => resolve( 'val1' ), 2000 ) ); var p2 = () => new Promise(  (resolve, reject) => setTimeout( () => resolve( 'val2' ), 2000 ) ); var p3 = () => new Promise(  (resolve, reject) => setTimeout( () => reject( 'err3' ), 2000 ) ); var p = Promise.allSettled( [p1(), p2(), p3()] ).then(  ( values ) => console.log( values ) ); //  [ {status: "fulfilled", value: "val1"}  {status: "fulfilled", value: "val2"}  {status: "rejected", value: "err3"} ] 

→ Support



▍ MĂ©thode Promise.any ()


La méthode Promise.any() est similaire à Promise.race() , mais la promesse retournée par elle n'exécute pas le catch lorsque l'une des promesses passées à cette méthode est rejetée.

Au lieu de cela, il attend la résolution de toutes les promesses. Si aucune promesse n'a été autorisée, le bloc catch sera exécuté. Si l'une des promesses est résolue avec succÚs, then sera exécutée.

Résumé


Dans cet article, nous avons examiné certaines des innovations JavaScript discutées lors de la conférence Google I / O 2019 . Nous espérons que vous y trouverez quelque chose qui vous sera utile.

Chers lecteurs! Qu'est-ce qui vous manque particuliĂšrement en JavaScript?

Source: https://habr.com/ru/post/fr464131/


All Articles