JavaScript-Innovationen: Ergebnisse von Google I / O 2019 Teil 2

Heute veröffentlichen wir den zweiten Teil der Übersetzung von JavaScript-Innovationen. Hier sprechen wir über Trennzeichen von Ziffern von Zahlen, über BigInt-Zahlen, über die Arbeit mit Arrays und Objekten, über globalThis , über das Sortieren, über die Internationalisierungs-API und über Versprechen.



Der erste Teil

Zahlentrennzeichen


Lange Zahlen in Programmen sind schwer zu lesen. Zum Beispiel ist 1000000000 eine Milliarde Dezimalstellen. Aber auf den ersten Blick ist es schwer zu verstehen. Wenn der Leser des Programms auf etwas Ähnliches stößt, muss er Nullen sorgfältig berücksichtigen, um es richtig wahrzunehmen.

In modernem JavaScript können Sie das Trennzeichen für Ziffern von Zahlen verwenden - einen Unterstrich ( _ ), dessen Verwendung die Lesbarkeit langer Zahlen verbessert. So sehen mit einem Trennzeichen geschriebene Zahlen im Code aus:

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

Separatoren können verwendet werden, um Zahlen willkürlich in Fragmente zu unterteilen. Beim Umgang mit Zahlen ignoriert JavaScript einfach Trennzeichen. Sie können beim Schreiben beliebiger Zahlen verwendet werden: Ganzzahlen, Gleitkomma, Binär, Hexadezimal, Oktal.

 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 

→ Unterstützung


  • TC39: Stufe 3
  • Chrome: 75+
  • Knoten: 12,5+

Bigint-Datentyp


Zahlen in JavaScript werden mit der Number .

Der Maximalwert, der mit dem Datentyp Number sicher dargestellt werden kann, ist (2⁵³ - 1), dh 9007199254740991. Sie können diese Nummer mit dem Konstrukt Number.MAX_SAFE_INTEGER .

Beachten Sie, dass JavaScript bei der Verwendung eines numerischen Literals im JS-Code dieses verarbeitet und mithilfe des Number Konstruktors ein darauf basierendes Objekt erstellt. Der Prototyp dieses Objekts enthält Methoden zum Arbeiten mit Zahlen. Dies geschieht bei allen primitiven Datentypen .

Was passiert, wenn wir versuchen, der Nummer 9007199254740991 etwas hinzuzufügen?

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

Das Ergebnis des Hinzufügens von Number.MAX_SAFE_INTEGER und 10, der zweiten Ausgabe des console.log() , ist falsch. Dies liegt daran, dass JS Berechnungen mit Zahlen, die größer als der Wert von Number.MAX_SAFE_INTEGER sind, nicht korrekt ausführen kann. Sie können dieses Problem mithilfe des Datentyps bigint .

Mit dem bigint Typ können bigint Ganzzahlen darstellen, die größer als Number.MAX_SAFE_INTEGER . Das Arbeiten mit BigInt-Werten ähnelt dem Arbeiten mit Werten vom Typ Number . Insbesondere verfügt die Sprache über die Funktion BigInt() , mit der Sie die entsprechenden Werte erstellen können, und den integrierten primitiven bigint Datentyp, der zur Darstellung großer Ganzzahlen verwendet wird.

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

JavaScript fügt n am Ende von BigInt-Literalen hinzu. Für uns bedeutet dies, dass solche Literale geschrieben werden können, indem n am Ende von ganzen Zahlen hinzugefügt wird.

Jetzt, da wir über BigInt-Zahlen verfügen, können wir sicher mathematische Operationen mit einer großen Anzahl von bigint Typen bigint .

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

Eine Anzahl von Typnummern ist nicht identisch mit einer Anzahl von Typ- bigint . Insbesondere sprechen wir über die Tatsache, dass BigInt-Zahlen nur ganze Zahlen sein können. Infolgedessen stellt sich heraus, dass Sie keine arithmetischen Operationen ausführen können, die die Typen bigint und number verwenden.

Es ist zu beachten, dass die Funktion BigInt() verschiedene Zahlen BigInt() kann: dezimal, binär, hexadezimal, oktal. Innerhalb dieser Funktion werden sie in Zahlen umgewandelt, für deren Darstellung das Dezimalzahlensystem verwendet wird.

Der bigint Typ unterstützt auch bigint :

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

→ Unterstützung



Neue Array-Methoden: .flat () und .flatMap ()


Hier werden wir über die neuen Prototypmethoden für das Array Objekt sprechen - die Methoden .flat() und .flatMap() .

▍ .flat () -Methode


Jetzt haben Objekte vom Typ Array eine neue Methode - .flat(n) . Es gibt ein neues Array zurück, mit dem die Elemente von Arrays rekursiv auf die angegebene Ebene n angehoben werden können. Standardmäßig ist n 1. Diese Methode kann n gleich Infinity , wodurch Sie ein Array mit verschachtelten Arrays in ein eindimensionales Array konvertieren können.

 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] 

→ Unterstützung



▍ .flatMap () -Methode


Bei der Lösung alltäglicher Aufgaben muss der Programmierer das Array manchmal mit der Methode .map() anschließend in eine flache Struktur umwandeln. Erstellen Sie beispielsweise ein Array mit den Zahlen und Quadraten dieser Zahlen:

 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] 

Die Lösung dieses Problems kann mithilfe der .flatMap() -Methode vereinfacht werden. Es konvertiert die Arrays, die von der an sie übergebenen Rückruffunktion zurückgegeben werden, genauso wie sie ihre .flat() -Methode mit dem Parameter n gleich 1 konvertieren würden.

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

→ Unterstützung



▍ Object.fromEntries () -Methode


Sie können : aus einem Objekt extrahieren : kann mit der statischen Object verwendet werden, die ein Array zurückgibt, von dem jedes Element ein Array ist, das als erstes Element den Schlüssel und als zweites den Wert enthält.

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

Jetzt steht uns eine statische Methode Object.fromEntries() , mit der wir eine ähnliche Struktur wieder in ein Objekt konvertieren können.

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

Die Methode entries() wurde verwendet, um das Filtern und Zuordnen von in Objekten gespeicherten Daten zu erleichtern. Das Ergebnis ist ein Array. Bisher hatte die Aufgabe, ein solches Array in ein Objekt umzuwandeln, keine schöne Lösung. Object.fromEntries() dieses Problem zu lösen, können Sie die Object.fromEntries() -Methode verwenden.

 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} 

Wenn die Map : -Datenstruktur zum Speichern des Paars : , werden die darin enthaltenen Daten in der Reihenfolge gespeichert, in der sie hinzugefügt wurden. Gleichzeitig ähnelt die Art und Weise, wie die Daten gespeichert werden, dem von der Object.entries() -Methode zurückgegebenen Array. Die Object.fromEntries() -Methode ist Object.fromEntries() einfach zum Transformieren von Kartendatenstrukturen in Objekte zu verwenden.

 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} 

→ Unterstützung



▍ Globale Eigenschaft globalThis


Wir kennen das in JavaScript verwendete this . Es hat keinen festen Wert. Stattdessen hängt die Bedeutung this ab, in welchem ​​Kontext darauf zugegriffen wird. In jeder Umgebung verweist das this auf ein globales Objekt, wenn über den Kontext der höchsten Ebene darauf zugegriffen wird. Dies ist die globale Bedeutung this .

In browserbasiertem JavaScript ist der globale Wert this beispielsweise das window . Sie können dies überprüfen, indem Sie das console.log(this) auf der obersten Ebene der JavaScript-Datei (im externesten Kontext) oder in der Browser-JS-Konsole verwenden.


Zugriff in der Browserkonsole

Der globale Wert in Node.js verweist auf ein global Objekt. In einem Web-Worker zeigt es auf den Worker selbst. Es ist jedoch keine leichte Aufgabe, den globalen Wert zu ermitteln. Tatsache ist, dass Sie sich nirgendwo darauf beziehen this . Wenn Sie dies beispielsweise im Konstruktor der Klasse versuchen, stellt sich heraus, dass this auf eine Instanz der entsprechenden Klasse verweist.

In einigen Umgebungen kann das this self verwendet werden, um auf den globalen Wert this zuzugreifen. Dieses Schlüsselwort spielt dieselbe Rolle wie die Mechanismen für den Zugriff auf diesen Wert in Browsern, in Node.js und in Web-Workern. Wenn Sie wissen, wie der globale Wert in verschiedenen Umgebungen aufgerufen wird, können Sie eine Funktion erstellen, die diesen Wert zurückgibt:

 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(); 

Vor uns liegt eine primitive Polyfüllung, um das globale this Objekt zu erhalten. Lesen Sie hier mehr darüber. JavaScript hat jetzt das Schlüsselwort globalThis . Es bietet eine universelle Möglichkeit, auf den globalen Wert this Programms für verschiedene Umgebungen zuzugreifen, und hängt nicht vom Speicherort des Programms ab, von dem aus auf es zugegriffen wird.

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

→ Unterstützung



Stabile Sortierung


Der ECMAScript-Standard bietet keinen bestimmten Array-Sortieralgorithmus, den JavaScript-Engines implementieren sollten. Es wird nur die zum Sortieren verwendete API beschrieben. Infolgedessen können bei Verwendung verschiedener JS-Engines Unterschiede in der Leistung von Sortiervorgängen und in der Stabilität (Stabilität) von Sortieralgorithmen auftreten.

Jetzt verlangt der Standard , dass Sortierarrays stabil sind. Details zur Sortierstabilität finden Sie hier . Das Wesentliche dieser Eigenschaft von Sortieralgorithmen ist wie folgt. Der Algorithmus ist stabil, wenn das Sortierergebnis, bei dem es sich um ein modifiziertes Array handelt, Elemente mit denselben Werten enthält, die von der Sortierung nicht betroffen waren, und zwar in derselben Reihenfolge, in der sie im ursprünglichen Array platziert wurden. Betrachten Sie ein Beispiel:

 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 }, ] 

Hier wird das Listenarray, das die Objekte enthält, nach dem age dieser Objekte sortiert. Im Listenarray befindet sich ein Objekt mit der Namenseigenschaft Barbra vor dem Objekt mit der Namenseigenschaft Natasha . Da die age dieser Objekte gleich sind, können wir erwarten, dass diese Elemente im sortierten Array die vorherige Anordnungsreihenfolge relativ zueinander beibehalten. In der Praxis war dies jedoch nicht zu erwarten. Wie genau das sortierte Array gebildet wird, hängt vollständig von der verwendeten JS-Engine ab.

Jetzt verwenden alle modernen Browser und Node.js einen stabilen Sortieralgorithmus, der beim Zugriff auf die Array-Methode .sort() wird. Auf diese Weise können Sie immer für dieselben Daten das gleiche Ergebnis erzielen:

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

In der Vergangenheit unterstützten einige JS-Engines eine stabile Sortierung, jedoch nur für kleine Arrays. Um die Leistung bei der Verarbeitung großer Arrays zu verbessern, könnten sie schnellere Algorithmen verwenden und die Sortierstabilität beeinträchtigen.

→ Unterstützung


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

Internationalisierungs-API


Die Internationalisierungs-API dient zum Organisieren von Zeichenfolgenvergleichen sowie zum Formatieren von Zahlen, Datums- und Uhrzeitangaben, wie dies in verschiedenen regionalen Standards (Gebietsschemas) üblich ist. Der Zugriff auf diese API wird über das Intl Objekt organisiert . Dieses Objekt bietet Konstruktoren zum Erstellen von Sortierobjekten und Objekten, die Daten formatieren. Die Liste der vom Intl Objekt unterstützten Gebietsschemas finden Sie hier .

▍Intl.RelativeTimeFormat ()


In vielen Anwendungen ist es häufig erforderlich, die Zeit in einem relativen Format auszugeben. Es kann so aussehen wie "vor 5 Minuten", "gestern", "vor 1 Minute" und so weiter. Wenn die Website-Materialien in verschiedene Sprachen übersetzt werden, müssen Sie alle möglichen Kombinationen relativer Konstruktionen, die die Zeit beschreiben, in die Site-Assembly aufnehmen.

JS verfügt jetzt über den Intl.RelativeTimeFormat(locale, config) , mit dem Sie Formatierungssysteme für Datum und Uhrzeit für verschiedene Gebietsschemas erstellen können. Insbesondere handelt es sich um Objekte mit der Methode .format(value, unit) , mit der Sie verschiedene relative Zeitstempel generieren können. Es sieht so aus:

 // 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 

→ Unterstützung



▍Intl.ListFormat ()


Mit dem Intl.ListFormat Konstruktor können Intl.ListFormat Listenelemente mit den Wörtern and ( ) und or ( ) kombinieren. Beim Erstellen des entsprechenden Objekts wird dem Konstruktor das Gebietsschema und das Objekt mit den Parametern übergeben. Der Typparameter kann conjunction , disjunction und unit . Wenn wir beispielsweise die Elemente des [apples, mangoes, bananas] mithilfe eines Konjunktionsobjekts kombinieren möchten, erhalten wir eine Zeichenfolge der Form apples, mangoes and bananas . Wenn wir ein Disjunktionsobjekt verwenden, erhalten wir eine Zeichenfolge der Form apples, mangoes or bananas .

Das vom Intl.ListFormat Konstruktor erstellte Objekt verfügt über eine .format(list) -Methode , die Listen kombiniert. Betrachten Sie ein Beispiel:

 // 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 

→ Unterstützung



▍Intl.Locale ()


Das Konzept des „regionalen Standards“ ist normalerweise viel mehr als nur der Name einer Sprache. Dies kann den Kalendertyp, Informationen zu den verwendeten Zeitzyklen und die Namen der Sprachen umfassen. Der Intl.Locale(localeId, config) Konstruktor Intl.Locale(localeId, config) verwendet, um formatierte Intl.Locale(localeId, config) basierend auf dem an ihn übergebenen config zu erstellen.

Intl.Locale mit Intl.Locale erstelltes Intl.Locale enthält alle angegebenen regionalen Einstellungen. Die Methode .toString() erzeugt eine formatierte regionale Standardzeichenfolge.

 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 

Hier können Sie Informationen zu Bezeichnern und Gebietsschema-Tags in Unicode lesen.

→ Unterstützung


  • TC39: Stufe 3
  • Chrome: 74+
  • Knoten: 12+

Versprechen


Ab sofort verfügt JS über die statischen Methoden Promise.all() und Promise.race() . Die Promise.all([...promises]) gibt ein Versprechen zurück, das erfolgreich aufgelöst wird, nachdem alle Versprechen, die als Argument an die Methode übergeben wurden, aufgelöst wurden. Dieses Versprechen wird abgelehnt, falls mindestens eines der darauf übertragenen Versprechen abgelehnt wird. Die Promise.race([...promises]) gibt ein Versprechen zurück, das aufgelöst wird, nachdem eines der übertragenen Versprechen aufgelöst wurde, und wird abgelehnt, wenn mindestens eines dieser Versprechen abgelehnt wird.

Die Community der JS-Entwickler suchte verzweifelt nach einer statischen Methode. Das zurückgegebene Versprechen wurde aufgelöst, nachdem alle an sie weitergegebenen Versprechen vollständig waren (zulässig oder abgelehnt). Außerdem brauchten wir eine Methode ähnlich wie race() , die ein Versprechen zurückgibt, das auf die Lösung eines der an sie übergebenen Versprechen wartet.

▍ Promise.allSettled () -Methode


Die Promise.allSettled() -Methode akzeptiert eine Reihe von Versprechungen. Das von ihm zurückgegebene Versprechen ist zulässig, nachdem alle Versprechen abgelehnt oder genehmigt wurden. Das Ergebnis ist, dass das von dieser Methode zurückgegebene Versprechen keinen catch .

Tatsache ist, dass dieses Versprechen immer erfolgreich gelöst wird. Der then Block erhält von jedem Versprechen status und value in der Reihenfolge, in der sie erscheinen.

 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"} ] 

→ Unterstützung



▍ Methode Promise.any ()


Die Promise.any() -Methode ähnelt Promise.race() , aber das von ihr zurückgegebene Versprechen führt den catch nicht aus, wenn eines der an diese Methode übergebenen Versprechen abgelehnt wird.

Stattdessen wartet er auf die Lösung aller Versprechen. Wenn keine Versprechungen erlaubt waren, wird der catch Block ausgeführt. Wenn eines der Versprechen erfolgreich gelöst wurde, wird es ausgeführt.

Zusammenfassung


In diesem Artikel haben wir uns einige der JavaScript-Innovationen angesehen, die auf der Google I / O 2019- Konferenz diskutiert wurden. Wir hoffen, dass Sie unter ihnen etwas finden, das Ihnen nützlich ist.

Liebe Leser! Was vermissen Sie besonders in JavaScript?

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


All Articles