Heute, im neunten Teil der Übersetzung des JavaScript-Handbuchs, wird ein Überblick über die Funktionen gegeben, die dank der Standards ES7, ES8 und ES9 in der Sprache erschienen sind.
→
Teil 1: Erstes Programm, Sprachfunktionen, Standards→
Teil 2: Codestil und Programmstruktur→
Teil 3: Variablen, Datentypen, Ausdrücke, Objekte→
Teil 4: Funktionen→
Teil 5: Arrays und Loops→
Teil 6: Ausnahmen, Semikolons, Platzhalterliterale→
Teil 7: Strict Mode, dieses Schlüsselwort, Ereignisse, Module, mathematische Berechnungen→
Teil 8: Übersicht über die ES6-Funktionen→
Teil 9: Übersicht über die ES7-, ES8- und ES9-Standards
ES7 Standard
Der ES7-Standard, der gemäß der offiziellen Terminologie ES2016 heißt, wurde im Sommer 2016 veröffentlicht. Er, im Vergleich zu ES6, in die Sprache gebracht, ist nicht viel neu. Insbesondere sprechen wir über Folgendes:
Array.prototype.includes()
-Methode.- Potenzierungsoperator.
▍ Methode Array.prototype.includes ()
Die Methode
Array.prototype.includes()
dient zum Überprüfen des Vorhandenseins eines Elements im Array. Wenn Sie das gewünschte Element im Array finden, wird
true
, nicht -
false
. Vor ES7 wurde die Methode
indexOf()
verwendet, um dieselbe Operation auszuführen. Wenn ein Element gefunden wird, wird der erste Index zurückgegeben, anhand dessen es im Array gefunden werden kann. Wenn
indexOf()
das Element nicht findet, gibt es die Zahl
-1
.
Gemäß den Konvertierungsregeln für JavaScript-Typen wird die Zahl
-1
in
true
konvertiert.
indexOf()
die Ergebnisse der Operation von
indexOf()
zu überprüfen
indexOf()
sollte daher eine nicht besonders bequeme Konstruktion der folgenden Form verwendet werden.
if ([1,2].indexOf(3) === -1) { console.log('Not found') }
Wenn in einer ähnlichen Situation unter der Annahme, dass
indexOf()
, ohne ein Element zu finden,
false
zurückgibt, etwas wie das unten gezeigte verwendet wird, funktioniert der Code nicht richtig.
if (![1,2].indexOf(3)) {
In diesem Fall stellt sich heraus, dass die Konstruktion
![1,2].indexOf(3)
false
ergibt.
Mit der
includes()
-Methode sehen solche Vergleiche viel logischer aus.
if (![1,2].includes(3)) { console.log('Not found') }
In diesem Fall gibt die Konstruktion
[1,2].includes(3)
false
, dieser Wert ist ein Operator
!
wird auf
true
und die Konsole erhält eine Meldung, dass das Element im Array nicht gefunden wurde.
▍ Potenzierungsoperator
Der Exponentiationsoperator führt dieselbe Funktion wie die
Math.pow()
-Methode aus, ist jedoch bequemer als eine Bibliotheksfunktion, da sie Teil der Sprache ist.
Math.pow(4, 2) == 4 ** 2
Dieser Operator kann als angenehme Ergänzung zu JS angesehen werden, was in Anwendungen nützlich ist, die bestimmte Berechnungen durchführen. Ein ähnlicher Operator existiert in anderen Programmiersprachen.
ES8 Standard
Der ES8-Standard (ES2017) wurde 2017 veröffentlicht. Er brachte wie ES7 nicht viel in die Sprache. Wir sprechen nämlich über die folgenden Merkmale:
- Hinzufügen von Zeichenfolgen zu einer bestimmten Länge.
- Methode
Object.values()
. - Methode
Object.entries()
. - Methode
Object.getOwnPropertyDescriptors()
. - Nachgestellte Kommas in Funktionsparametern.
- Asynchrone Funktionen.
- Arbeiten Sie mit Shared Memory und atomaren Operationen.
▍ Hinzufügen von Zeilen zu einer bestimmten Länge
ES8 führte zwei neue
String
Objektmethoden ein -
padStart()
und
padEnd()
.
Die
padStart()
-Methode füllt die aktuelle Zeile mit einer weiteren Zeile, bis die letzte Zeile die gewünschte Länge erreicht hat. Das Befüllen erfolgt am Zeilenanfang (links). Hier erfahren Sie, wie Sie diese Methode verwenden.
str.padStart(targetLength [, padString])
Hier ist
str
die aktuelle Zeile,
targetLength
die Länge der letzten Zeile (wenn sie kleiner als die Länge der aktuellen Zeile ist, wird diese Zeile ohne Änderungen zurückgegeben),
padString
ist ein optionaler Parameter - die Zeile, die zum Füllen der aktuellen Zeile verwendet wird. Wenn
padString
nicht angegeben ist, wird ein Leerzeichen verwendet,
padString
aktuelle Zeile auf die angegebene Länge
padString
.
Die
padEnd()
-Methode ähnelt
padStart()
, die Zeile wird jedoch rechts ausgefüllt.
Betrachten Sie Beispiele für die Verwendung dieser Methoden.
const str = 'test'.padStart(10) const str1 = 'test'.padEnd(10,'*') console.log(`'${str}'`)
Hier wurden bei Verwendung von
padStart()
mit nur der gewünschten Länge der resultierenden Zeichenfolge Leerzeichen am Anfang der ursprünglichen Zeichenfolge hinzugefügt. Bei Verwendung von
padEnd()
mit der Länge der letzten Zeile und der zu füllenden Zeile wurden die Zeichen
*
am Ende der ursprünglichen Zeile hinzugefügt.
▍ Methode Object.values ()
Diese Methode gibt ein Array zurück, das die Werte der eigenen Eigenschaften des Objekts enthält, dh die Eigenschaften, die das Objekt selbst enthält, und nicht diejenigen, auf die es über die Prototypkette zugreifen kann.
Hier erfahren Sie, wie Sie es verwenden.
const person = { name: 'Fred', age: 87 } const personValues = Object.values(person) console.log(personValues)
Diese Methode gilt auch für Arrays.
▍ Methode Object.entries ()
Diese Methode gibt ein Array zurück, von dem jedes Element auch ein Array ist, das im Format
[key, value]
Schlüssel und Werte der eigenen Eigenschaften des Objekts enthält.
const person = { name: 'Fred', age: 87 } const personValues = Object.entries(person) console.log(personValues)
Wenn Sie diese Methode auf Arrays anwenden, werden die Indizes der Elemente als Schlüssel angezeigt, und was im Array an den entsprechenden Indizes gespeichert ist, wird als Werte angezeigt.
▍ Methode getOwnPropertyDescriptors ()
Diese Methode gibt Informationen zu allen Eigenschaften des Objekts zurück. Attributmengen (Deskriptoren) sind Objekteigenschaften zugeordnet. Insbesondere sprechen wir über die folgenden Attribute:
value
- Der Wert der Eigenschaft des Objekts.writable
- enthält true
wenn die Eigenschaft geändert werden kann.get
- enthält eine Getter-Funktion, die der Eigenschaft zugeordnet ist, oder, falls keine solche Funktion vorhanden ist, undefined
.set
- enthält die Setter-Funktion für die Eigenschaft oder undefined
.configurable
- wenn es false
- die Eigenschaft kann nicht gelöscht werden, ihre Attribute können außer dem Wert nicht geändert werden.enumerable
- Wenn true in dieser Eigenschaft enthalten ist, ist die
aufzählbar.
Hier erfahren Sie, wie Sie diese Methode verwenden.
Object.getOwnPropertyDescriptors(obj)
Es nimmt ein Objekt, dessen Eigenschaftsinformationen Sie herausfinden müssen, und gibt ein Objekt zurück, das diese Informationen enthält.
const person = { name: 'Fred', age: 87 } const propDescr = Object.getOwnPropertyDescriptors(person) console.log(propDescr)
Warum wird diese Methode benötigt? Tatsache ist, dass Sie damit kleine Kopien von Objekten erstellen und diese kopieren können, zusätzlich zu anderen Eigenschaften, Gettern und Setzern. Dies konnte nicht mit der
Object.assign()
-Methode durchgeführt werden, die im ES6-Standard zum Kopieren von Objekten enthalten war.
Das folgende Beispiel enthält ein Objekt mit einem Setter, das mithilfe von
console.log()
anzeigt, was in die entsprechende Eigenschaft geschrieben werden soll.
const person1 = { set name(newName) { console.log(newName) } } person1.name = 'x'
Versuchen wir, dieses Objekt mit der Methode
assign()
zu kopieren.
const person2 = {} Object.assign(person2, person1) person2.name = 'x'
Wie Sie sehen können, funktioniert dieser Ansatz nicht. Die
name
Eigenschaft, die der Setter im ursprünglichen Objekt war, wird jetzt als reguläre Eigenschaft dargestellt.
Jetzt kopieren wir das Objekt mit den Methoden
Object.defineProperties()
(es erschien in ES5.1) und
Object.getOwnPropertyDescriptors()
.
const person3 = {} Object.defineProperties(person3, Object.getOwnPropertyDescriptors(person1)) person3.name = 'x'
Hier bleibt der Setter in der Kopie des Objekts.
Es ist zu beachten, dass die für
Object.assign()
spezifischen Einschränkungen auch für die
Object.create()
-Methode charakteristisch sind, wenn sie zum Klonen von Objekten verwendet werden.
▍Vollendungskommas in Funktionsparametern
Mit dieser Funktion können Sie beim Deklarieren und beim Aufrufen von Funktionen ein Komma am Ende der Liste der Parameter bzw. Argumente lassen.
const doSomething = ( var1, var2, ) => {
Dies verbessert die Benutzerfreundlichkeit von Versionskontrollsystemen. Wir sprechen nämlich von der Tatsache, dass Sie beim Hinzufügen neuer Parameter zu einer Funktion den vorhandenen Code nicht nur zum Einfügen eines Kommas ändern müssen.
▍Asynchrone Funktionen
Das Konstrukt
async/await
ist im ES2017-Standard enthalten, der als wichtigste Neuerung dieser Sprachversion angesehen werden kann.
Asynchrone Funktionen sind eine Kombination aus Versprechungen und Generatoren. Sie vereinfachen Konstruktionen, für deren Beschreibung zuvor eine große Menge an Vorlagencode und unbequeme Versprechungsketten erforderlich waren. In der Tat sprechen wir über eine Abstraktion auf hoher Ebene über Versprechen.
Als im ES2015-Standard Versprechungen auftauchten, wurden sie entwickelt, um bestehende Probleme mit asynchronem Code zu lösen, was sie auch taten. In den zwei Jahren, in denen die Standards ES2015 und ES2017 geteilt wurden, wurde jedoch klar, dass Versprechen nicht als endgültige Lösung für diese Probleme angesehen werden können.
Die Versprechen zielten insbesondere darauf ab, das Problem der „Rückrufhölle“ zu lösen, aber nachdem sie dieses Problem gelöst hatten, zeigten sie selbst aufgrund der Komplexität des Codes, in dem sie verwendet werden, nicht ihre beste Seite. Tatsächlich löst die asynchrone
async/await
Konstruktion das Problem der Versprechen und verbessert die Verwendbarkeit von asynchronem Code.
Betrachten Sie ein Beispiel.
function doSomethingAsync() { return new Promise((resolve) => { setTimeout(() => resolve('I did something'), 3000) }) } async function doSomething() { console.log(await doSomethingAsync()) } console.log('Before') doSomething() console.log('After')
Dieser Code gibt Folgendes an die Konsole aus.
Before After I did something
Wie Sie sehen,
doSomething()
Programm nach dem Aufruf von
doSomething()
weiter ausgeführt, nachdem
Before
, Nachher in der Konsole angezeigt wurde und nachdem drei Sekunden vergangen sind, habe
I did something
.
Serieller asynchroner Funktionsaufruf
Bei Bedarf können asynchrone Funktionen so etwas wie Aufrufketten bilden. Solche Designs zeichnen sich durch eine bessere Lesbarkeit aus als ähnliche, die ausschließlich auf Versprechungen beruhen. Dies ist im folgenden Beispiel zu sehen.
function promiseToDoSomething() { return new Promise((resolve)=>{ setTimeout(() => resolve('I did something'), 10000) }) } async function watchOverSomeoneDoingSomething() { const something = await promiseToDoSomething() return something + ' and I watched' } async function watchOverSomeoneWatchingSomeoneDoingSomething() { const something = await watchOverSomeoneDoingSomething() return something + ' and I watched as well' } watchOverSomeoneWatchingSomeoneDoingSomething().then((res) => { console.log(res)
▍ Shared Memory und atomare Operationen
Hier geht es um das
SharedArrayBuffer- Objekt, mit dem Sie gemeinsam genutzte Speicherbereiche beschreiben können, und das
Atomics- Objekt, das eine Reihe von atomaren Operationen in Form statischer Methoden enthält. Details zu den Möglichkeiten, die diese Objekte dem Programmierer bieten, finden Sie
hier .
ES9 Standard
ES9 (ES2018) ist die neueste Version des Standards zum Zeitpunkt der Veröffentlichung dieses Materials. Hier sind die Hauptmerkmale:
- Wenden Sie Spread- und Rest-Anweisungen auf Objekte an.
- Asynchrone Iteratoren.
- Methode
Promise.prototype.finally()
. - Verbesserungen des regulären Ausdrucks.
▍Anwendung von Spread- und Rest-Operatoren auf Objekte
Wir haben bereits über die übrigen und verbreiteten Operatoren gesprochen, die in ES6 erschienen sind und für die Arbeit mit Arrays verwendet werden können. Beide sehen aus wie drei Punkte. Mit dem Rest-Operator im folgenden Beispiel für die Destrukturierung eines Arrays können Sie das erste und das zweite Element in die Konstanten
first
und
second
und den Rest in die Konstante
others
.
const numbers = [1, 2, 3, 4, 5] const [first, second, ...others] = numbers console.log(first)
Mit dem
spread
Operator können Sie Arrays an Funktionen übergeben, die regelmäßige Parameterlisten erwarten.
const numbers = [1, 2, 3, 4, 5] const sum = (a, b, c, d, e) => a + b + c + d + e const res = sum(...numbers) console.log(res)
Mit demselben Ansatz können Sie jetzt mit Objekten arbeiten. Hier ist ein Beispiel für die Verwendung der rest-Anweisung in einer destruktiven Zuweisungsoperation.
const { first, second, ...others } = { first: 1, second: 2, third: 3, fourth: 4, fifth: 5 } console.log(first)
Hier ist die Spread-Anweisung, die beim Erstellen eines neuen Objekts basierend auf einem vorhandenen Objekt verwendet wird. Dieses Beispiel setzt das vorherige fort.
const items = { first, second, ...others } console.log(items)
▍Asynchrone Iteratoren
Mit dem neuen
for-await-of
Konstrukt können Sie asynchrone Funktionen aufrufen, die Versprechen in Schleifen zurückgeben. Solche Schleifen warten auf die Lösung des Versprechens, bevor sie mit dem nächsten Schritt fortfahren. So sieht es aus.
for await (const line of readLines(filePath)) { console.log(line) }
Gleichzeitig sollte beachtet werden, dass solche Schleifen in asynchronen Funktionen verwendet werden sollten - genauso wie bei der Arbeit mit dem Konstrukt
async/await
.
▍ Promise.prototype.finally () -Methode
Wenn das Versprechen erfolgreich gelöst wurde, wird die nächste
then()
-Methode aufgerufen. Wenn etwas schief geht, wird die
catch()
-Methode aufgerufen. Mit der Methode
finally()
können Sie Code ausführen, unabhängig davon, was zuvor passiert ist.
fetch('file.json') .then(data => data.json()) .catch(error => console.error(error)) .finally(() => console.log('finished'))
▍ Verbesserungen des regulären Ausdrucks
Reguläre Ausdrücke können Zeichenfolgen nachträglich überprüfen (
?<=
). Auf diese Weise können Sie in den Zeilen nach bestimmten Konstruktionen suchen, vor denen sich einige andere Konstruktionen befinden.
Die Möglichkeit, Überprüfungen mit dem Konstrukt
?=
Vorangehen zu können, war in regulären Ausdrücken vorhanden, die vor dem ES2018-Standard in JavaScript implementiert wurden. Solche Überprüfungen zeigen an, ob ein anderes Fragment einem bestimmten Fragment einer Zeile folgt.
const r = /Roger(?= Waters)/ const res1 = r.test('Roger is my dog') const res2 = r.test('Roger is my dog and Roger Waters is a famous musician') console.log(res1)
Bau
?!
führt die entgegengesetzte Operation aus - eine Übereinstimmung wird nur gefunden, wenn eine andere Zeile nicht der angegebenen Zeile folgt.
const r = /Roger(?! Waters)/g const res1 = r.test('Roger is my dog') const res2 = r.test('Roger is my dog and Roger Waters is a famous musician') console.log(res1)
Bei der nachträglichen Überprüfung wird, wie bereits erwähnt, die Konstruktion
?<=
Verwendet.
const r = /(?<=Roger) Waters/ const res1 = r.test('Pink Waters is my dog') const res2 = r.test('Roger is my dog and Roger Waters is a famous musician') console.log(res1)
Die der beschriebenen entgegengesetzte Operation kann mit der Konstruktion
?<!
.
const r = /(?<!Roger) Waters/ const res1 = r.test('Pink Waters is my dog') const res2 = r.test('Roger is my dog and Roger Waters is a famous musician') console.log(res1)
Unicode-Regex-Escape-Sequenzen
In regulären Ausdrücken können Sie die Klasse
\d
, die einer beliebigen Ziffer entspricht, die Klasse
\s
, die einem beliebigen Leerzeichen entspricht, die Klasse
\w
, die einem beliebigen alphanumerischen Zeichen entspricht, usw. Die betreffende Funktion erweitert den Satz von Klassen, die in regulären Ausdrücken verwendet werden können, sodass Sie mit Unicode-Sequenzen arbeiten können. Wir sprechen über die Klasse
\p{}
und die Umkehrung der Klasse
\P{}
.
In Unicode verfügt jedes Zeichen über eine Reihe von Eigenschaften. Diese Eigenschaften sind in geschweiften Klammern der Gruppe
\p{}
. Beispielsweise bestimmt die
Script
Eigenschaft die Sprachfamilie, zu der ein Zeichen gehört. Die logische
ASCII
Eigenschaft
true
für ASCII-Zeichen usw. Wir werden beispielsweise herausfinden, ob einige Zeilen nur ASCII-Zeichen enthalten.
console.log(r.test('abc'))
Die Eigenschaft
ASCII_Hex_Digit
true
nur für Zeichen, die zum Schreiben von Hexadezimalzahlen verwendet werden können.
const r = /^\p{ASCII_Hex_Digit}+$/u console.log(r.test('0123456789ABCDEF'))
Es gibt viele andere ähnliche Eigenschaften, die auf die gleiche Weise wie oben beschrieben verwendet werden. Unter ihnen sind
Uppercase
,
Lowercase
,
White_Space
,
Alphabetic
,
Emoji
.
Im
Script
erfahren Sie beispielsweise, wie Sie mithilfe der
Script
Eigenschaft bestimmen, welches Alphabet in einer Zeichenfolge verwendet wird. Hier überprüfen wir die Zeichenfolge auf die Verwendung des griechischen Alphabets.
const r = /^\p{Script=Greek}+$/u console.log(r.test('ελληνικά'))
Details zu diesen Eigenschaften finden Sie
hier .
Benannte Gruppen
Erfasste Zeichengruppen in ES2018 können mit Namen versehen werden. So sieht es aus.
const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/ const result = re.exec('2015-01-02') console.log(result)
Ohne die Verwendung benannter Gruppen wären dieselben Daten nur als Array-Elemente verfügbar.
const re = /(\d{4})-(\d{2})-(\d{2})/ const result = re.exec('2015-01-02') console.log(result)
Regex-Flagge s
Die Verwendung des
s
Flags führt zu einem Zeichen
.
(Punkt) stimmt unter anderem mit dem Zeilenumbruchzeichen überein. Ohne dieses Flag entspricht ein Punkt einem beliebigen Zeichen mit Ausnahme einer neuen Zeile.
console.log(/hi.welcome/.test('hi\nwelcome'))
Zusammenfassung
Mit diesem Material schließen wir die Veröffentlichung der Übersetzungen
dieses JavaScript-Handbuchs ab. Wir hoffen, dass diese Veröffentlichungen denjenigen, die zuvor noch nicht mit JavaScript gearbeitet hatten, geholfen haben, ihre ersten Schritte bei der Programmierung in dieser Sprache zu unternehmen.
Liebe Leser! Wenn Sie noch nie in JS geschrieben und diese Sprache in diesem Handbuch beherrschen, teilen Sie uns bitte Ihre Eindrücke mit.
