JavaScript-Handbuch Teil 8: Überblick über die ES6-Funktionen

Ursprünglicher Autor: Flavio Copes
  • Übersetzung
  • Tutorial
Heute, im achten Teil der Übersetzung des JavaScript-Handbuchs, werden wir die Funktionen der Sprache überprüfen, die nach der Veröffentlichung des ES6-Standards darin enthalten war. Auf die eine oder andere Weise sind wir früher auf viele dieser Möglichkeiten gestoßen, die wir uns irgendwo genauer angeschaut haben, irgendwo als selbstverständlich erachtet haben. Dieser Abschnitt des Handbuchs soll zusammen mit der Offenlegung einiger Themen, die wir bisher noch nicht angesprochen haben, das Wissen eines unerfahrenen Entwicklers auf dem Gebiet des modernen JavaScript verbessern.

Teil 1: Erstes Programm, Sprachmerkmale, Standards
Teil 2: Codestil und Programmstruktur
Teil 3: Variablen, Datentypen, Ausdrücke, Objekte
Teil 4: Funktionen
Teil 5: Arrays und Schleifen
Teil 6: Ausnahmen, Semikolons, Vorlagenliterale
Teil 7: strikter Modus, dieses Schlüsselwort, Ereignisse, Module, mathematische Berechnungen
Teil 8: Überblick über die ES6-Standardfunktionen
Teil 9: Überblick über die ES7-, ES8- und ES9-Standards



Über ES6


Der ES6-Standard, der korrekter wäre, ES2015 oder ECMAScript 2015 zu nennen (dies sind die offiziellen Namen, obwohl alle ihn als ES6 bezeichnen), erschien 4 Jahre nach der Veröffentlichung des vorherigen Standards - ES5.1. Es dauerte ungefähr zehn Jahre, um alles zu entwickeln, was zum ES5.1-Standard gehörte. Heutzutage ist alles, was in diesem Standard enthalten ist, zu den üblichen Werkzeugen des JS-Entwicklers geworden. Es ist zu beachten, dass ES6 wesentliche Änderungen an der Sprache vorgenommen hat (während die Abwärtskompatibilität zu früheren Versionen beibehalten wurde). Um das Ausmaß dieser Änderungen einschätzen zu können, ist anzumerken, dass das Dokument, das den ES5-Standard beschreibt, ungefähr 250 Seiten umfasst, und dass der Standard ES6 in einem Dokument beschrieben ist, das bereits ungefähr 600 Seiten umfasst.

Die Liste der wichtigsten Neuerungen des ES2015-Standards kann Folgendes umfassen:

  • Pfeilfunktionen
  • Versprechen
  • Generatoren
  • Schlüsselwörter letundconst
  • Klassen
  • Module
  • Template Literal Support
  • Unterstützung für Standardfunktionsparameter
  • Spread-Operator
  • Zerstörerische Zuordnung
  • Objektliterale erweitern
  • Zyklus for...of
  • Unterstützung für Datenstrukturen MapundSet

Betrachten Sie diese Möglichkeiten.

Pfeilfunktionen


Pfeilfunktionen haben das Erscheinungsbild von JavaScript-Code geändert. Ihre Verwendung macht Funktionsdeklarationen optisch kürzer und einfacher. Hier ist die Deklaration einer regulären Funktion.

const foo = function foo() {
  //...
}

Aber fast die gleiche (wenn auch nicht ganz ähnliche) Pfeilfunktion.

const foo = () => {
  //...
}

Wenn der Hauptteil der Pfeilfunktion nur aus einer Zeile besteht, deren Ergebnis von dieser Funktion zurückgegeben werden muss, wird sie noch kürzer geschrieben.

const foo = () => doSomething()

Wenn die Pfeilfunktion nur einen Parameter akzeptiert, können Sie diesen wie folgt schreiben.

const foo = param => doSomething(param)

Es sollte beachtet werden, dass mit dem Aufkommen von Pfeilfunktionen gewöhnliche Funktionen nicht verschwunden sind, sie können weiterhin im Code verwendet werden, sie funktionieren auf die gleiche Weise wie zuvor.

Dieses Schlüsselwort wird in Pfeilfunktionen verwendet


Pfeilfunktionen haben keinen Eigenwert this, sondern erben ihn aus dem Ausführungskontext.

Damit ist das Problem beseitigt, bei dem bei Verwendung normaler Funktionen Konstrukte wie diese verwendet werden mussten, um den Kontext zu erhalten var that = this. Wie in den vorherigen Teilen des Handbuchs gezeigt, wirkt sich diese Änderung jedoch erheblich auf die Funktionen zum Arbeiten mit Pfeilfunktionen und auf den Umfang ihrer Anwendung aus.

Versprechen


Mit Hilfe von Versprechungen können Sie das bekannte Problem der „Rückruf-Hölle“ loswerden, obwohl deren Verwendung die Verwendung komplexer Strukturen impliziert. Dieses Problem wurde im ES2017-Standard mit der Einführung eines async/awaitauf Versprechungen basierenden Designs behoben .

JavaScript-Entwickler verwendeten Versprechen vor dem ES2015-Standard und verwendeten dafür verschiedene Bibliotheken (z. B. jQuery, q, deferred.js, vow). Dies zeigt die Wichtigkeit und Relevanz dieses Mechanismus. Verschiedene Bibliotheken setzen es auf unterschiedliche Weise um, die Herausbildung eines Standards in diesem Bereich kann als sehr positive Tatsache gewertet werden.
Hier wird Code mit Rückruffunktionen (Callbacks) geschrieben.

setTimeout(function() {
  console.log('I promised to run after 1s')
  setTimeout(function() {
    console.log('I promised to run after 2s')
  }, 1000)
}, 1000)

Unter Verwendung von Versprechungen kann dies wie folgt umgeschrieben werden.

const wait = () => new Promise((resolve, reject) => {
  setTimeout(resolve, 1000)
})
wait().then(() => {
  console.log('I promised to run after 1s')
  return wait()
})
.then(() => console.log('I promised to run after 2s'))

Generatoren


Generatoren sind spezielle Funktionen, die ihre eigene Ausführung anhalten und wieder aufnehmen können. Dadurch kann ein anderer Code ausgeführt werden, während sich der Generator im Leerlauf befindet.

Der Generator entscheidet selbständig, dass er anhalten und einen anderen Code "warten" muss, bis er an der Reihe ist. Gleichzeitig hat der Generator die Möglichkeit, die Ausführung fortzusetzen, nachdem die Ergebnisse, auf die er wartet, abgeschlossen sind.

All dies geschieht dank eines einzigen einfachen Schlüsselworts yield. Wenn dieses Schlüsselwort im Generator gefunden wird, wird die Ausführung angehalten.
Ein Generator kann viele Zeilen mit diesem Schlüsselwort enthalten und seine Ausführung mehrmals unterbrechen. Generatoren werden mit Konstruktion deklariert *function. Dieses Sternchen vor einem Wort functionsollte nicht für einen Zeiger-Dereferenzierungsoperator verwendet werden, der in Sprachen wie C, C ++ oder Go verwendet wird.

Generatoren markieren das Aufkommen eines neuen JavaScript-Programmierparadigmas. Insbesondere bieten sie die Möglichkeit zum bidirektionalen Datenaustausch zwischen dem Generator und anderem Code und ermöglichen es Ihnen, langlebige Zyklen zu erstellen while, die das Programm nicht "anhalten".

Betrachten Sie ein Beispiel, das die Merkmale des Betriebs von Generatoren veranschaulicht. Hier ist der Generator selbst.

function *calculator(input) {
    var doubleThat = 2 * (yield (input / 2))
    var another = yield (doubleThat)
    return (input * doubleThat * another)
}

Mit diesem Befehl initialisieren wir es.

const calc = calculator(10)

Dann wenden wir uns seinem Iterator zu.

calc.next()

Dieser Befehl startet einen Iterator und gibt ein solches Objekt zurück.

{
  done: false
  value: 5
}

Hier passiert folgendes. Der Code führt eine Funktion aus, die den inputan den Generator-Konstruktor übergebenen Wert verwendet. Der Generatorcode wird solange ausgeführt, bis ein Schlüsselwort darin gefunden wird yield. In diesem Moment gibt es das Ergebnis der Division inputdurch zurück 2, was, da es inputgleich ist 10, eine Zahl ergibt 5. Diese Zahl erhalten wir dank des Iterators, und zusammen mit ihr erhalten wir einen Hinweis darauf, dass der Generator noch nicht abgeschlossen ist (die Eigenschaft donein dem vom Iterator zurückgegebenen Objekt ist auf value gesetzt false), dh , die Funktion wurde nur angehalten.
Wenn der Iterator das nächste Mal aufgerufen wird, übergeben wir eine Nummer an den Generator 7.

calc.next(7)

Als Antwort darauf gibt der Iterator das nächste Objekt an uns zurück.

{
  done: false
  value: 14
}

Hier wurde die Zahl 7zur Berechnung des Wertes verwendet doubleThat.

Auf den ersten Blick scheint der Code input / 2so etwas wie ein Argument für eine Funktion zu sein, aber dies ist nur der Wert, der bei der ersten Iteration zurückgegeben wird. Hier überspringen wir diesen Wert und verwenden den neuen Eingabewert 7, multiplizieren ihn mit 2. Danach gelangen wir zum zweiten Schlüsselwort yield, wodurch der in der zweiten Iteration erhaltene Wert gleich ist 14.

Bei der nächsten Iteration, bei der es sich um die letzte handelt, übergeben wir eine Nummer an den Generator 100.

calc.next(100)

Als Antwort erhalten wir das folgende Objekt.

{
  done: true
  value: 14000
}

Die Iteration ist abgeschlossen (das Schlüsselwort wird im Generator nicht mehr gefunden yield), das Ergebnis der Auswertung des Ausdrucks wird im Objekt zurückgegeben (input * doubleThat * another), das heißt, 10 * 14 * 100die Vervollständigung des Iterators ( done: true) wird angezeigt .

Schlüsselwörter let und const


JavaScript hat immer ein Schlüsselwort verwendet, um Variablen zu deklarieren var. Solche Variablen haben einen Funktionsumfang. Mit Schlüsselwörtern letbzw. constkönnen Variablen und Konstanten deklariert werden, die einen Blockbereich haben.

Dies bedeutet, dass z. B. eine Variable, die mit einem Schlüsselwort letin einer Schleife, in einem Block ifoder in einem regulären Codeblock mit geschweiften Klammern deklariert wurde, diesen Block nicht überschreitet. Mit Hilfe deklarierte Variablen varsind nicht in solchen Blöcken enthalten und werden in der Funktion verfügbar, auf deren Ebene sie deklariert wurden.

Das Schlüsselwort constfunktioniert genauso let, aber damit werden unveränderliche Konstanten deklariert.

In modernem JS-Code wird das Schlüsselwort varselten verwendet. Es gab Platz für die Schlüsselwörter letund const. Gleichzeitig, was ungewöhnlich erscheinen mag, wird das Schlüsselwort constheutzutage sehr häufig verwendet, was die Popularität der Ideen der Immunität von Entitäten in der modernen Programmierung anzeigt.

Klassen


Es stellte sich heraus, dass JavaScript die einzige extrem verbreitete Sprache ist, die das Prototyp-Vererbungsmodell verwendet. Programmierer, die von Sprachen, die den klassenbasierten Vererbungsmechanismus implementieren, zu JS wechseln, fühlten sich in einer solchen Umgebung unwohl. Mit dem ES2015-Standard wurde die Klassenunterstützung in JavaScript eingeführt. Dies ist im Wesentlichen „syntaktischer Zucker“ um JS-interne Mechanismen, die Prototypen verwenden. Dies wirkt sich jedoch darauf aus, wie genau JS-Anwendungen schreiben.

JavaScript-Vererbungsmechanismen sehen jetzt in anderen objektorientierten Sprachen ähnlich aus.

class Person {
  constructor(name) {
    this.name = name
  }
  hello() {
    return 'Hello, I am ' + this.name + '.'
  }
}
class Actor extends Person {
  hello() {
    return super.hello() + ' I am an actor.'
  }
}
var tomCruise = new Actor('Tom Cruise')
console.log(tomCruise.hello()) 

Dieses Programm zeigt Text in der Konsole an Hello, I am Tom Cruise. I am an actor.
In JS-Klassen können Instanzvariablen nicht deklariert werden, sondern müssen in den Konstruktoren initialisiert werden.

Класса Klassenkonstruktor


Klassen haben eine spezielle Methode, constructordie aufgerufen wird, wenn eine Instanz der Klasse mit dem Schlüsselwort erstellt wird new.

▍ Schlüsselwort super


Mit dem Schlüsselwort superkönnen Sie von untergeordneten Klassen aus auf die übergeordnete Klasse zugreifen.

▍ Getter und Setter


Der Getter für eine Eigenschaft kann wie folgt festgelegt werden.

class Person {
  get fullName() {
    return `${this.firstName} ${this.lastName}`
  }
}

Der Einsteller kann wie folgt beschrieben werden.

class Person {
  set age(years) {
    this.theAge = years
  }
}

Sie arbeiten mit Gettern und Setzern, als wären sie keine Funktionen, sondern gewöhnliche Eigenschaften von Objekten.

Module


Vor dem ES2015-Standard gab es verschiedene konkurrierende Ansätze für die Arbeit mit Modulen. Insbesondere sprechen wir über RequireJS- und CommonJS-Technologien. Diese Situation führte zu Meinungsverschiedenheiten in der Community der JS-Entwickler.

Heutzutage normalisiert sich die Situation dank der Standardisierung der Module in ES2015 allmählich.

▍ Module importieren


Module werden mithilfe eines Ansichtskonstrukts importiert import...from.... Hier sind einige Beispiele.

import * as something from 'mymodule'
import React from 'react'
import { React, Component } from 'react'
import React as MyLibrary from 'react'

▍ Export von Modulen


Die internen Mechanismen des Moduls sind von außen geschlossen, aber aus dem Modul können Sie alles exportieren, was es anderen Modulen bieten kann. Dies geschieht mit dem Schlüsselwort export.

export var foo = 2
export function bar() { /* ... */ }

▍ Vorlagenliterale


Vorlagenliterale sind eine neue Möglichkeit, Zeichenfolgen in JavaScript zu beschreiben. So sieht es aus.

const aString = `A string`

Darüber hinaus können Sie mithilfe der Syntax von Vorlagenliteralen Ausdrücke in Zeichenfolgen einbetten und diese interpolieren. Dies geschieht mit dem View-Design ${a_variable}. Hier ist ein einfaches Beispiel für seine Verwendung:

const v = 'test'
const str = `something ${v}` //something test

Hier ist ein komplizierteres Beispiel, das die Möglichkeit veranschaulicht, Ausdrücke auszuwerten und ihre Ergebnisse in eine Zeichenfolge zu ersetzen.

const str = `something ${1 + 2 + 3}`
const str2 = `something ${foo() ? 'x' : 'y' }`

Dank der Verwendung von Template-Literalen ist es jetzt viel einfacher, mehrzeilige Strings zu deklarieren.

const str3 = `Hey
this
string
is awesome!`

Vergleichen Sie dies mit dem, was Sie tun mussten, um mehrzeilige Zeichenfolgen zu beschreiben, wenn Sie die Funktionen verwenden, die in der Sprache vor ES2015 verfügbar waren.

var str = 'One\n' +
'Two\n' +
'Three'

Standardfunktionsparameter


Jetzt unterstützen Funktionen die standardmäßig verwendeten Parameter - für den Fall, dass die entsprechenden Argumente beim Aufruf von Funktionen nicht an sie übergeben werden.

const foo = function(index = 0, testing = true) { /* ... */ }
foo()

Spread-Operator


Mit dem Ausbreitungsoperator (Erweiterungsoperator) können Sie Arrays, Objekte oder Zeichenfolgen „erweitern“. Dieser Operator sieht aus wie drei Punkte ( ...). Betrachten Sie es zunächst anhand eines Array-Beispiels.

const a = [1, 2, 3]

So erstellen Sie ein neues Array, das auf diesem Array basiert.

const b = [...a, 4, 5, 6]

So erstellen Sie eine Kopie des Arrays.

const c = [...a]

Dieser Operator arbeitet auch mit Objekten. Beispiel: Hier erfahren Sie, wie Sie damit ein Objekt klonen.

const newObj = { ...oldObj }

Wenn Sie den Spread-Operator auf eine Zeichenfolge anwenden, können Sie ihn in ein Array konvertieren, von dem jedes Element ein Zeichen aus dieser Zeichenfolge enthält.

const hey = 'hey'
const arrayized = [...hey] // ['h', 'e', 'y']

Dieser Operator ist zusätzlich zu den obigen Varianten seiner Anwendung nützlich, wenn Funktionen aufgerufen werden, die eine normale Liste von Argumenten erwarten, und ihnen ein Array mit diesen Argumenten übergeben werden.

const f = (foo, bar) => {}
const a = [1, 2]
f(...a)

Bisher wurde hierfür ein Ansichtskonstrukt verwendet f.apply(null, a), aber ein solcher Code ist schwieriger zu schreiben und weniger lesbar.

Zerstörerische Zuordnung


Die Destrukturierungszuweisungstechnik ermöglicht es beispielsweise, ein Objekt zu nehmen, einige Werte daraus zu extrahieren und sie in benannte Variablen oder Konstanten zu setzen.

const person = {
  firstName: 'Tom',
  lastName: 'Cruise',
  actor: true,
  age: 54,
}
const {firstName: name, age} = person

Hier werden die Eigenschaften firstNameund vom Objekt abgerufen age. Die Eigenschaft wird agesofort in die mit demselben Namen deklarierte Konstante geschrieben, und die Eigenschaft firstNamefällt nach der Extraktion in die Konstante name.

Die destruktive Zuweisung eignet sich auch zum Arbeiten mit Arrays.

const a = [1,2,3,4,5]
const [first, second, , , fifth] = a

Die Konstanten first, secondund fifthfallen jeweils ersten, zweiten und fünften Feldelemente.

Objektliterale erweitern


ES2015 hat die Möglichkeiten zur Beschreibung von Objekten mithilfe von Objektliteralen erheblich erweitert.

▍ Vereinfachung der Einbeziehung von Variablen in Objekte


Bisher musste die folgende Konstruktion verwendet werden, um einer Eigenschaft eines Objekts eine Variable zuzuweisen.

const something = 'y'
const x = {
  something: something
}

Nun kann das Gleiche so gemacht werden.

const something = 'y'
const x = {
  something
}

▍ Prototypen


Der Prototyp des Objekts kann jetzt mit der folgenden Konstruktion festgelegt werden.

const anObject = { y: 'y' }
const x = {
  __proto__: anObject
}

▍ Schlüsselwort super


Mit dem Schlüsselwort können superObjekte auf Prototypobjekte zugreifen. Zum Beispiel, um ihre Methoden aufzurufen, die denselben Namen haben wie die Methoden dieser Objekte.

const anObject = { y: 'y', test: () => 'zoo' }
const x = {
  __proto__: anObject,
  test() {
    return super.test() + 'x'
  }
}
x.test() //zoox

▍ Berechnete Eigenschaftsnamen


Berechnete Eigenschaftsnamen werden in der Phase der Objekterstellung gebildet.

const x = {
  ['a' + '_' + 'b']: 'z'
}
x.a_b //z

Für ... der Schleife


Im Jahr 2009 erschienen im ES5-Standard Zyklen forEach(). Dies ist eine nützliche Konstruktion, deren Nachteil die Tatsache ist, dass solche Zyklen sehr unpraktisch zu unterbrechen sind. Der klassische Zyklus forin Situationen, in denen die Ausführung des Zyklus vor seiner normalen Beendigung unterbrochen werden muss, ist eine viel geeignetere Wahl.

In ES2015 for...ofist ein Zyklus erschienen , der sich zum einen durch kurze Syntax und Bequemlichkeit auszeichnet forEachund zum anderen die Möglichkeit eines vorzeitigen Ausstiegs aus dem Zyklus unterstützt.

Hier einige Beispiele für Schleifen for...of.

//перебор значений элементов массива
for (const v of ['a', 'b', 'c']) {
  console.log(v);
}
//перебор значений элементов массива с выводом их индексов благодаря использованию метода entries()
for (const [i, v] of ['a', 'b', 'c'].entries()) {
  console.log(i, v);
}

Datenstrukturen zuordnen und festlegen


Die ES2015 erschien Datenstruktur Mapund Set(wie auch ihre „schwachen“ Optionen WeakMapund WeakSetderen Verwendung können Sie die Leistung von „Garbage Collector“ verbessern - der Mechanismus für die Speicherverwaltung in den JS-Motoren). Dies sind sehr beliebte Datenstrukturen, die vor dem Erscheinen ihrer offiziellen Implementierung mit den verfügbaren Sprachwerkzeugen nachgebildet werden mussten.

Zusammenfassung


Heute haben wir die Funktionen des ES2015-Standards überprüft, die den aktuellen Zustand der Sprache stark beeinflusst haben. Unser nächstes Thema werden Funktionen der ES2016-, ES2017- und ES2018-Standards sein.

Sehr geehrte Leser! Welche Neuerungen des ES6-Standards finden Sie am nützlichsten?


Jetzt auch beliebt: