Das Material, dessen erster Teil der Übersetzung wir heute veröffentlichen, ist den neuen Standard-JavaScript-Funktionen gewidmet, die auf der
Google I / O 2019- Konferenz erörtert wurden. Insbesondere werden wir hier über reguläre Ausdrücke, über Klassenfelder und über die Arbeit mit Zeichenfolgen sprechen.

Überprüfungen des regulären Ausdrucks
Reguläre Ausdrücke (kurz RegEx oder RegExp) sind eine leistungsstarke String-Verarbeitungstechnologie, die in vielen Programmiersprachen implementiert ist. Reguläre Ausdrücke sind sehr nützlich, wenn Sie beispielsweise nach Fragmenten von Zeichenfolgen anhand komplexer Muster suchen müssen. Bis vor kurzem hatte die JavaScript-Implementierung regulärer Ausdrücke alles andere als Lookbackhinds.
Um zu verstehen, was eine retrospektive Überprüfung ist, sprechen wir zunächst über Lookaheads, die bereits in JavaScript unterstützt werden.
→
Der zweite Teil▍ Vorabprüfung
Die Syntax führender Prüfungen in regulären Ausdrücken ermöglicht es Ihnen, nach Fragmenten von Zeichenfolgen zu suchen, wenn bekannt ist, dass sich andere Fragmente rechts davon befinden. Wenn Sie beispielsweise mit der Zeichenfolge
MangoJuice, VanillaShake, GrapeJuice
Sie die Syntax eines positiven führenden Checks verwenden, um die Wörter zu finden, auf die unmittelbar das Wort
Juice
folgt. In unserem Fall sind dies die Wörter
Mango
und
Grape
.
Es gibt zwei Arten von Leitprüfungen. Dies sind positive Lookaheads und negative Lookaheads.
Positive Bleiprüfung
Eine positive Leitprüfung wird verwendet, um nach Zeilen zu suchen, rechts davon andere, zuvor bekannte Zeilen sind. So sieht die für diese Prüfung verwendete Syntax für reguläre Ausdrücke aus:
/[a-zA-Z]+(?=Juice)/
Mit dieser Vorlage können Sie Wörter auswählen, die aus Klein- oder Großbuchstaben bestehen, gefolgt vom Wort
Juice
. Verwechseln Sie keine Strukturen, die führende und retrospektive Prüfungen beschreiben, mit Erfassungsgruppen. Obwohl die Bedingungen dieser Prüfungen in Klammern angegeben sind, erfasst das System sie nicht. Schauen wir uns ein Beispiel für eine positive Lead-Prüfung an.
const testString = "MangoJuice, VanillaShake, GrapeJuice"; const testRegExp = /[a-zA-Z]+(?=Juice)/g; const matches = testString.match( testRegExp ); console.log( matches );
Negative Bleiprüfung
Wenn wir anhand der obigen Zeile den Wirkungsmechanismus negativer Leitschecks betrachten, stellt sich heraus, dass Sie damit Wörter finden können, rechts von denen es kein Wort
Juice
. Die Syntax von negativen führenden Prüfungen ähnelt der Syntax von positiven Prüfungen. Es gibt jedoch ein Merkmal: Das Symbol
=
(gleich) ändert sich in ein Symbol
!
(Ausrufezeichen). So sieht es aus:
/[a-zA-Z]+(?!Juice)/
Mit diesem regulären Ausdruck können Sie alle Wörter auswählen, rechts von denen es kein Wort
Juice
. Beim Anwenden einer solchen Vorlage werden jedoch alle Wörter in der Zeile ausgewählt (
MangoJuice, VanillaShake, GrapeJuice
). Tatsache ist, dass laut System hier kein einziges Wort mit
Juice
endet. Um das gewünschte Ergebnis zu erzielen, müssen Sie daher den regulären Ausdruck klarstellen und wie folgt umschreiben:
/(Mango|Vanilla|Grape)(?!Juice)/
Mit dieser Vorlage können Sie die Wörter
Mango
,
Vanilla
oder
Grape
auswählen.
Mango
gibt es kein Wort
Juice
. Hier ist ein Beispiel:
const testString = "MangoJuice, VanillaShake, GrapeJuice"; const testRegExp = /(Mango|Vanilla|Grape)(?!Juice)/g; const matches = testString.match( testRegExp ); console.log( matches );
▍ Rückblick
In Analogie zur Syntax führender Prüfungen können Sie mit der Syntax retrospektiver Prüfungen nur dann Zeichenfolgen auswählen, wenn links von diesen Folgen ein bestimmtes Muster steht. Wenn Sie beispielsweise die Zeichenfolge
FrozenBananas, DriedApples, FrozenFish
können Sie eine positive retrospektive Prüfung verwenden, um Wörter zu finden, links davon das Wort
Frozen
. In unserem Fall entsprechen die Wörter
Bananas
und
Fish
diesem Zustand.
Es gibt, wie es bei führenden Prüfungen der Fall ist, positive nachträgliche Prüfungen (positives Aussehen) und negative nachträgliche Prüfungen (negatives oder negatives Aussehen).
Positive retrospektive Bewertung
Positive retrospektive Überprüfungen werden verwendet, um nach Mustern zu suchen, links davon andere Muster sind. Hier ist ein Beispiel für die Syntax, mit der solche Überprüfungen beschrieben werden:
/(?<=Frozen)[a-zA-Z]+/
Hier wird das Symbol
<
verwendet, das nicht in der Beschreibung der führenden Prüfungen enthalten war. Außerdem befindet sich die Bedingung im regulären Ausdruck nicht rechts von der für uns interessanten Vorlage, sondern links. Mit der obigen Vorlage können Sie alle Wörter auswählen, die mit
Frozen
. Betrachten Sie ein Beispiel:
const testString = "FrozenBananas, DriedApples, FrozenFish"; const testRegExp = /(?<=Frozen)[a-zA-Z]+/g; const matches = testString.match( testRegExp ); console.log( matches );
Negative retrospektive Prüfung
Mit dem Mechanismus negativer retrospektiver Überprüfungen können Sie in den Zeilen links nach Mustern suchen, für die kein Muster angegeben ist. Wenn Sie beispielsweise Wörter auswählen müssen, die nicht mit
Frozen
in der
FrozenBananas, DriedApples, FrozenFish
, können Sie versuchen, diesen regulären Ausdruck zu verwenden:
/(?<!Frozen)[a-zA-Z]+/
Da die Verwendung dieser Konstruktion jedoch zur Auswahl aller Wörter aus der Zeichenfolge führt, muss der reguläre Ausdruck geklärt werden, da keines von ihnen mit
Frozen
beginnt.
/(?<!Frozen)(Bananas|Apples|Fish)/
Hier ist ein Beispiel:
const testString = "FrozenBananas, DriedApples, FrozenFish"; const testRegExp = /(?<!Frozen)(Bananas|Apples|Fish)/g; const matches = testString.match( testRegExp ); console.log( matches );
→ Unterstützung
Dieser und ähnliche Abschnitte enthalten Informationen zum Stadium der Harmonisierung der beschriebenen Merkmale von JS im Technischen Komitee 39 (Technisches Komitee 39, TC39), das in ECMA International für die Unterstützung der ECMAScript-Spezifikationen verantwortlich ist. In solchen Abschnitten werden auch Daten zu Versionen von Chrome und Node.js (und manchmal zur Version von Firefox) bereitgestellt, mit denen Sie die entsprechenden Funktionen nutzen können.
Klassenfelder
Ein Klassenfeld ist ein neues Syntaxkonstrukt, mit dem die Eigenschaften von Klasseninstanzen (Objekten) außerhalb des Klassenkonstruktors definiert werden. Es gibt zwei Arten von Klassenfeldern: öffentliche Klassenfelder und private Klassenfelder.
▍Öffentliche Klassenfelder
Bis vor kurzem mussten die Eigenschaften von Objekten im Klassenkonstruktor definiert werden. Diese Eigenschaften waren öffentlich (öffentlich). Dies bedeutet, dass auf sie zugegriffen werden kann, indem mit einer Instanz der Klasse (Objekt) gearbeitet wird. Hier ist ein Beispiel für die Deklaration eines öffentlichen Eigentums:
class Dog { constructor() { this.name = 'Tommy'; } }
Wenn eine Klasse erstellt werden musste, die eine bestimmte übergeordnete Klasse erweitert, musste im Konstruktor der untergeordneten Klasse
super()
aufgerufen werden. Dies musste durchgeführt werden, bevor der untergeordneten Klasse eigene Eigenschaften hinzugefügt werden konnten. So sieht es aus:
class Animal {} class Dog extends Animal { constructor() { super();
Dank des Erscheinungsbilds der Syntax öffentlicher Felder einer Klasse ist es möglich, Klassenfelder außerhalb des Konstruktors zu beschreiben. Das System ruft implizit
super()
.
class Animal {} class Dog extends Animal { sound = 'Woof! Woof!';
Beim impliziten Aufruf von
super()
werden alle Argumente, die der Benutzer beim Erstellen der Klasseninstanz angegeben hat, an ihn übergeben (dies ist das Standardverhalten von JavaScript, private Klassenfelder haben nichts Besonderes). Wenn der Konstruktor der übergeordneten Klasse Argumente benötigt, die auf spezielle Weise vorbereitet wurden, müssen Sie
super()
selbst aufrufen. Sehen Sie sich die Ergebnisse des impliziten Konstruktoraufrufs der übergeordneten Klasse an, wenn Sie eine Instanz der untergeordneten Klasse erstellen.
class Animal { constructor( ...args ) { console.log( 'Animal args:', args ); } } class Dog extends Animal { sound = 'Woof! Woof!';
▍ Private Klassenfelder
Wie Sie wissen, gibt es in JavaScript keine Zugriffsmodifikatoren für Klassenfelder wie
public
,
private
oder
protected
. Alle Eigenschaften von Objekten sind standardmäßig öffentlich. Dies bedeutet, dass der Zugriff auf sie unbegrenzt ist. Am nächsten daran, eine Eigenschaft eines Objekts einer privaten Eigenschaft ähnlich zu machen, ist die Verwendung des Datentyps
Symbol
. Auf diese Weise können Sie die Eigenschaften von Objekten vor der Außenwelt verbergen. Möglicherweise haben Sie Eigenschaftsnamen verwendet, denen ein
_
(Unterstrich) vorangestellt ist, um anzugeben, dass die entsprechenden Eigenschaften nur für die Verwendung innerhalb des Objekts vorgesehen sind. Dies ist jedoch nur eine Art Benachrichtigung für diejenigen, die die Einrichtung nutzen werden. Dies löst nicht das Problem einer echten Einschränkung des Zugangs zu Immobilien.
Dank des Mechanismus privater Klassenfelder ist es möglich, die Klasseneigenschaften nur innerhalb dieser Klasse zugänglich zu machen. Dies führt dazu, dass von außen nicht auf sie zugegriffen werden kann und mit einer Instanz der Klasse (Objekt) gearbeitet wird. Nehmen Sie das vorherige Beispiel und versuchen Sie, von außen auf die Eigenschaft der Klasse zuzugreifen, wenn das Präfix
_
verwendet wurde.
class Dog { _sound = 'Woof! Woof!';
Wie Sie sehen können, löst die Verwendung des Präfixes
_
unser Problem nicht. Private Felder von Klassen können wie öffentliche Felder deklariert werden. Anstelle eines Präfixes in Form eines Unterstrichs müssen Sie ihren Namen jedoch ein Präfix in Form eines Nummernzeichens (
#
) hinzufügen. Ein Versuch eines nicht autorisierten Zugriffs auf das auf diese Weise deklarierte Privateigentum des Objekts führt zu folgendem Fehler:
SyntaxError: Undefined private field
Hier ist ein Beispiel:
class Dog { #sound = 'Woof! Woof!';
Beachten Sie, dass auf private Eigenschaften nur von der Klasse aus zugegriffen werden kann, in der sie deklariert sind. Daher können Nachkommenklassen ähnliche Eigenschaften der übergeordneten Klasse nicht direkt verwenden.
Private (und öffentliche) Felder können deklariert werden, ohne bestimmte Werte in sie zu schreiben:
class Dog { #name; constructor( name ) { this.#name = name; } showName() { console.log( this.#name ); } }
→ Unterstützung
- TC39: Stufe 3
- Chrome: 74+
- Knoten: 12+
String-Methode .matchAll ()
Der Prototyp des
String
Datentyps verfügt über eine
.match()
-Methode, die ein Array von String-Fragmenten zurückgibt, die der durch den regulären Ausdruck angegebenen Bedingung entsprechen. Hier ist ein Beispiel mit dieser Methode:
const colors = "#EEE, #CCC, #FAFAFA, #F00, #000"; const matchColorRegExp = /([A-Z0-9]+)/g; console.log( colors.match( matchColorRegExp ) );
Bei Verwendung dieser Methode werden jedoch keine zusätzlichen Informationen (wie Indizes) zu den gefundenen Fragmenten der Zeichenfolge angegeben. Wenn Sie das
g
Flag aus dem regulären Ausdruck entfernen, der an die
.match()
-Methode übergeben wird, wird ein Array zurückgegeben, das zusätzliche Informationen zu den Suchergebnissen enthält. Bei diesem Ansatz wird jedoch nur das erste Fragment der Zeichenfolge gefunden, das dem regulären Ausdruck entspricht.
const colors = "#EEE, #CCC, #FAFAFA, #F00, #000"; const matchColorRegExp = /#([A-Z0-9]+)/; console.log( colors.match( matchColorRegExp ) );
Um etwas Ähnliches zu erhalten, müssen Sie für mehrere Fragmente eines Strings die Methode des regulären Ausdrucks
.exec()
. Die dafür erforderlichen Konstruktionen sind komplizierter als die, bei denen eine einzelne Zeichenfolgenmethode verwendet würde, um ähnliche Ergebnisse zu erzielen. Insbesondere benötigen wir hier eine
while
, die ausgeführt wird, bis
.exec()
null
zurückgibt.
.exec()
diesem Ansatz, dass
.exec()
keinen Iterator
.exec()
.
const colors = "#EEE, #CCC, #FAFAFA, #F00, #000"; const matchColorRegExp = /#([A-Z0-9]+)/g;
Um solche Probleme zu lösen, können wir jetzt die String-Methode
.matchAll()
, die einen Iterator zurückgibt. Jeder Aufruf der
.next()
-Methode dieses Iterators
.next()
nächste Element aus den Suchergebnissen zurück. Infolgedessen kann das obige Beispiel wie folgt umgeschrieben werden:
const colors = "#EEE, #CCC, #FAFAFA, #F00, #000"; const matchColorRegExp = /#([A-Z0-9]+)/g; console.log( ...colors.matchAll( matchColorRegExp ) );
→ Unterstützung
Benannte Gruppen in regulären Ausdrücken
Das Konzept von Gruppen in der JavaScript-Implementierung von Mechanismen für reguläre Ausdrücke unterscheidet sich geringfügig von der Implementierung eines ähnlichen Konzepts in anderen Sprachen. Wenn die RegEx-Vorlage unter Verwendung von JavaScript in Klammern gesetzt wird (außer wenn Klammern für retrospektive oder erweiterte Prüfungen verwendet werden), wird die Vorlage zu einer Gruppe.
Die von der Gruppe erfassten Fragmente der Zeichenfolge spiegeln sich in den Ergebnissen der Anwendung des regulären Ausdrucks wider.
Im vorherigen Beispiel konnten Sie sehen, dass das erste Element des Arrays mit den Suchergebnissen dasjenige ist, das dem gesamten regulären Ausdruck entspricht, und das zweite Element dasjenige, das der Gruppe entspricht. Hier ist dieses Array-Element:
["#EEE", "EEE", index: 0, input: "<colors>"]
Wenn der reguläre Ausdruck mehrere Gruppen enthält, werden die Ergebnisse der Verarbeitung der Zeichenfolge in der Reihenfolge ihrer Beschreibung im regulären Ausdruck angezeigt. Betrachten Sie ein Beispiel:
const str = "My name is John Doe."; const matchRegExp = /My name is ([az]+) ([az]+)/i; const result = str.match( matchRegExp );console.log( result );
Hier sehen Sie, dass die erste Zeile der Ausgabe die gesamte Zeile ist, die dem regulären Ausdruck entspricht. Das zweite und dritte Element repräsentieren, was von den Gruppen erfasst wurde.
Mit benannten Gruppen können Sie speichern, welche Gruppen im Gruppenobjekt erfasst werden, dessen Eigenschaftsnamen den Namen entsprechen, die Gruppen zugewiesen wurden.
const str = "My name is John Doe."; const matchRegExp = /My name is (?<firstName>[az]+) (?<lastName>[az]+)/i; const result = str.match( matchRegExp ); console.log( result ); console.log( result.groups );
Es ist zu beachten, dass benannte Gruppen gut mit der Methode
.matchAll()
.
→ Unterstützung
- TC39: Stufe 4
- Chrome: 64+
- Knoten: 10+
Fortsetzung folgt…
Liebe Leser! Haben Sie eine der hier beschriebenen JavaScript-Innovationen verwendet?
