10th May 2017
JavaScript hat in den letzten Jahren eine Menge Fortschritte gemacht. Wenn Sie 2017 JavaScript lernen und ES6 nicht berührt haben, verpassen Sie eine einfachere Möglichkeit, JavaScript zu lesen und zu schreiben.
Keine Sorge, wenn Sie JavaScript noch nicht beherrschen. Sie müssen nicht großartig in JavaScript sein, um die zusätzlichen Boni zu nutzen, die ES6 Ihnen bietet. In diesem Artikel möchte ich Ihnen acht ES6-Funktionen vorstellen, die ich täglich als Entwickler verwende, um Ihnen den Einstieg in die neue Syntax zu erleichtern.
- Eine Liste der ES6-Funktionen
- Let und const
- Lass vs var
- Let vs const
- Pfeilfunktionen
- Das Wesentliche der Pfeilfunktionen
- Das lexikalische this
- Standardparameter
- Destrukturierung
- Destrukturierung von Objekten
- Destrukturierende Arrays
- Variablen mit destrukturierten Arrays austauschen
- Destrukturierung von Arrays und Objekten beim Deklarieren von Funktionen
- Der Rest-Parameter und der Spread-Operator
- Der Rest-Parameter
- Der Spread-Operator
- Erweiterte Objektliterale
- Eigenschaftswert-Abkürzungen
- Method shorthands
- Berechnete Objekteigenschaftsnamen
- Template-Literale
- Einpacken
Eine Liste der ES6-Funktionen
Zunächst einmal ist ES6 ein großes Update für JavaScript. Hier ist eine große Liste von Funktionen, wenn Sie neugierig sind, was neu ist, dank Luke Hoban:
- Pfeile
- Klassen
- Erweiterte Objektliterale
- Vorlagenzeichenfolgen
- Destrukturierung
- Standard + rest + spread
- Let + const
- Iteratoren + für…von
- Generatoren
- Unicode
- Module
- Modullader
- Map + set + weakmap + weakset
- Proxies
- Symbole
- Unterklassierbare eingebaute
- Versprechen
- Math + number + string + array + object apis
- Binäre und oktale Literale
- Reflect api
- Tail anrufe
Lassen Sie sich von dieser großen Liste von Funktionen nicht von ES6 abschrecken. Sie müssen nicht alles sofort wissen. Ich werde mit Ihnen acht dieser Funktionen teilen, die ich täglich verwende. Sie sind:
- Let und const
- Pfeilfunktionen
- Standardparameter
- Destrukturierung
- Rest-Parameter und Spread-Operator
- Erweiterte Objektliterale
- Template-Literale
- Versprechen
Wir werden gehen Sie die acht Funktionen in den folgenden Abschnitten durch. Im Moment werde ich die ersten fünf Funktionen durchgehen. Ich werde den Rest hinzufügen, wie ich entlang in den nächsten paar Wochen gehen.
Übrigens ist die Browserunterstützung für ES6 erstaunlich. Fast alles wird nativ unterstützt, wenn Sie für die neuesten Browser (Edge und die neuesten Versionen von FF, Chrome und Safari) codieren.
Sie benötigen keine ausgefallenen Werkzeuge wie Webpack, wenn Sie ES6 schreiben möchten. Wenn in Ihrem Fall die Browserunterstützung fehlt, können Sie jederzeit auf von der Community erstellte Polyfills zurückgreifen. Google sie einfach 🙂
Damit springen wir in die erste Funktion.
Let und const
In ES5 (dem alten JavaScript) sind wir es gewohnt, Variablen mit dem Schlüsselwort var
zu deklarieren. In ES6 kann dieses var
-Schlüsselwort durch let
und const
ersetzt werden, zwei leistungsstarke Schlüsselwörter, die die Entwicklung vereinfachen.
Schauen wir uns zunächst den Unterschied zwischen let
und var
an, um zu verstehen, warum let
und const
besser sind.
Lass vs var
Lass uns zuerst über var
sprechen, da wir damit vertraut sind.
Zunächst können wir Variablen mit dem Schlüsselwort var
deklarieren. Einmal deklariert, kann diese Variable überall im aktuellen Bereich verwendet werden.
var me = 'Zell'console.log(me) // Zell
Im obigen Beispiel habe ich me
als globale Variable deklariert. Diese globale Variable me
kann auch in einer Funktion wie dieser verwendet werden:
var me = 'Zell'function sayMe () { console.log(me)}sayMe() // Zell
Das Gegenteil ist jedoch nicht der Fall. Wenn ich eine Variable in einer Funktion deklariere, kann ich sie nicht außerhalb der Funktion verwenden.
function sayMe() { var me = 'Zell' console.log(me)}sayMe() // Zellconsole.log(me) // Uncaught ReferenceError: me is not defined
Wir können also sagen, dass var
funktionsbezogen ist. Das heißt, wenn eine Variable mit var
in einer Funktion erstellt wird, existiert sie nur innerhalb der Funktion.
Wenn die Variable außerhalb der Funktion erstellt wird, existiert sie im äußeren Bereich.
var me = 'Zell' // global scopefunction sayMe () { var me = 'Sleepy head' // local scope console.log(me)}sayMe() // Sleepy headconsole.log(me) // Zell
let
, auf der anderen Seite ist Block-scoped. Das heißt, wenn eine Variable mit let
erstellt wird, existiert sie nur innerhalb ihres Blocks.
Aber warte, was ist ein Block?
Ein Block in JavaScript ist alles innerhalb eines Paares geschweifter Klammern. Im Folgenden finden Sie Beispiele für Blöcke.
{ // new scope block}if (true) { // new scope block}while (true) { // new scope block}function () { // new block scope}
Der Unterschied zwischen Variablen mit Blockbereich und Funktionsbereich ist enorm. Wenn Sie eine Variable mit Funktionsbereich verwenden, können Sie versehentlich eine Variable überschreiben, ohne dies zu beabsichtigen. Hier ein Beispiel:
var me = 'Zell'if (true) { var me = 'Sleepy head'}console.log(me) // 'Sleepy head'
In diesem Beispiel können Sie sehen, dass me
nach dem Durchlaufen des if
-Blocks zu Sleepy head
wird. Dieses Beispiel wird wahrscheinlich keine Probleme für Sie verursachen, da Sie wahrscheinlich keine Variablen mit demselben Namen deklarieren werden.
Aber jeder, der mit var
in einer for
Schleifensituation arbeitet, kann aufgrund der Art und Weise, wie Variablen definiert werden, auf etwas Seltsames stoßen. Betrachten Sie den folgenden Code, der die Variable i
viermal protokolliert und dann i
erneut mit einer setTimeout
-Funktion protokolliert.
for (var i = 1; i < 5; i++) { console.log(i) setTimeout(function () { console.log(i) }, 1000)};
Was würden Sie von diesem Code erwarten? Hier ist, was tatsächlich passiert
Wie zum Teufel wurde i
viermal innerhalb der Timeout-Funktion zu 5
? Nun, es stellt sich heraus, dass der Wert von i
bereits vor der Ausführung der Timeout-Funktion zu 4
wurde, da var
funktionsbezogen ist.
Um den korrekten i
-Wert innerhalb von setTimeout
zu erhalten, der später ausgeführt wird, müssen wir eine andere Funktion erstellen, z. B. logLater
, um sicherzustellen, dass der i
-Wert nicht durch die for
-Schleife geändert wird, bevor setTimeout
ausgeführt wird:
function logLater (i) { setTimeout(function () { console.log(i) })}for (var i = 1; i < 5; i++) { console.log(i) logLater(i)};
( Dies wird übrigens als Schließung bezeichnet).
Die gute Nachricht ist, dass funktionsbezogene Verrücktheit wie das for-Loop-Beispiel, das ich Ihnen gerade gezeigt habe, bei let
nicht auftritt. Das gleiche Timeout-Beispiel, das wir zuvor geschrieben haben, könnte so geschrieben werden, und es funktioniert sofort, ohne zusätzliche Funktionen zu schreiben:
for (let i = 1; i < 5; i++) { console.log(i) setTimeout(function () { console.log(i) }, 1000)};
Wie Sie sehen, vereinfachen Variablen mit Blockbereich die Entwicklung erheblich, indem häufige Fehler mit Variablen mit Funktionsbereich entfernt werden. Um das Leben einfacher zu machen, empfehle ich Ihnen, let
über var
zu verwenden, wenn Sie von nun an JavaScript-Variablen deklarieren. (ES6 ist das neue JavaScript bereits 😎).
Jetzt wissen wir, was let
tut, gehen wir zum Unterschied zwischen let
und const
über.
Let vs const
Wie let
ist auch const
blockiert. Der Unterschied besteht darin, dass const
nach der Deklaration nicht neu zugewiesen werden kann.
const name = 'Zell'name = 'Sleepy head' // TypeError: Assignment to constant variable.let name1 = 'Zell'name1 = 'Sleepy head'console.log(name1) // 'Sleepy head'
Da const
nicht neu zugewiesen werden kann, sind sie gut für Variablen, die sich nicht ändern würden.
Angenommen, ich habe eine Schaltfläche, mit der ein Modal auf meiner Website gestartet wird. Ich weiß, dass es nur einen Knopf geben wird, und es würde sich nicht ändern. In diesem Fall kann ich const
verwenden.
const modalLauncher = document.querySelector('.jsModalLauncher')
Wenn ich Variablen deklariere, bevorzuge ich immer const
gegenüber let
, wann immer dies möglich ist, da ich den zusätzlichen Hinweis erhalte, dass die Variable nicht neu zugewiesen wird. Dann benutze ich let
für alle anderen Situationen.
Als nächstes gehen wir weiter und sprechen über Pfeilfunktionen.
Pfeilfunktionen
Pfeilfunktionen werden durch den fetten Pfeil (=>
) gekennzeichnet, den Sie überall im ES6-Code sehen. Es ist eine Abkürzung, um anonyme Funktionen zu erstellen. Sie können überall dort verwendet werden, wo das Schlüsselwort function
verwendet wird. Zum Beispiel:
let array = // ES5 wayvar moreThan20 = array.filter(function (num) { return num > 20})// ES6 waylet moreThan20 = array.filter(num => num > 20)
Pfeilfunktionen sind ziemlich cool. Sie helfen, Code kürzer zu machen, was weniger Raum für Fehler gibt, sich zu verstecken. Sie helfen Ihnen auch, Code zu schreiben, der leichter zu verstehen ist, sobald Sie sich an die Syntax gewöhnt haben.
Lassen Sie uns in das Wesentliche der Pfeilfunktionen eintauchen, damit Sie lernen, sie zu erkennen und zu verwenden.
Das Wesentliche der Pfeilfunktionen
Lassen Sie uns zunächst über das Erstellen von Funktionen sprechen. In JavaScript sind Sie wahrscheinlich daran gewöhnt, Funktionen auf diese Weise zu erstellen:
function namedFunction() { // Do something}// using the functionnamedFunction()
Es gibt eine zweite Methode zum Erstellen von Funktionen. Sie können eine anonyme Funktion erstellen und einer Variablen zuweisen. Um eine anonyme Funktion zu erstellen, lassen wir ihren Namen aus der Funktionsdeklaration heraus.
var namedFunction = function() { // Do something}
Eine dritte Möglichkeit, Funktionen zu erstellen, besteht darin, sie direkt als Argument für eine andere Funktion oder Methode zu erstellen. Dieser dritte Anwendungsfall ist der häufigste für anonyme Funktionen. Hier ein Beispiel:
// Using an anonymous function in a callbackbutton.addEventListener('click', function() { // Do something})
Da ES6-Pfeilfunktionen eine Abkürzung für anonyme Funktionen sind, können Sie Pfeilfunktionen überall dort ersetzen, wo Sie eine anonyme Funktion erstellen.
So sieht es aus:
// Normal Functionconst namedFunction = function (arg1, arg2) { /* do your stuff */}// Arrow Functionconst namedFunction2 = (arg1, arg2) => {/* do your stuff */}// Normal function in a callbackbutton.addEventListener('click', function () { // Do something})// Arrow function in a callbackbutton.addEventListener('click', () => { // Do something})
Sehen Sie die Ähnlichkeit hier? Grundsätzlich entfernen Sie das Schlüsselwort function
und ersetzen es durch =>
an einer etwas anderen Stelle.
Aber was ist das große Problem mit Pfeilfunktionen? Ersetzen wir nicht einfach function
durch =>
?
Nun, es stellt sich heraus, dass wir nicht nur function
durch =>
ersetzen. Die Syntax einer Pfeilfunktion kann sich abhängig von zwei Faktoren ändern:
- Die Anzahl der erforderlichen Argumente
- Ob Sie eine implizite Rückgabe wünschen.
Der erste Faktor ist die Anzahl der Argumente, die der Pfeilfunktion übergeben werden. Wenn Sie nur ein Argument angeben, können Sie die Klammer entfernen, die die Argumente umgibt. Wenn keine Argumente erforderlich sind, können Sie die Klammer (()
) durch einen Unterstrich (_
) ersetzen.
Alle folgenden Funktionen sind gültige Pfeilfunktionen.
const zeroArgs = () => {/* do something */}const zeroWithUnderscore = _ => {/* do something */}const oneArg = arg1 => {/* do something */}const oneArgWithParenthesis = (arg1) => {/* do something */}const manyArgs = (arg1, arg2) => {/* do something */}
Der zweite Faktor für Pfeilfunktionen ist, ob Sie eine implizite Rückgabe wünschen. Pfeilfunktionen erstellen standardmäßig automatisch ein return
-Schlüsselwort, wenn der Code nur eine Zeile einnimmt und nicht in einem Block eingeschlossen ist.
Diese beiden sind also äquivalent:
const sum1 = (num1, num2) => num1 + num2const sum2 = (num1, num2) => { return num1 + num2 }
Diese beiden Faktoren sind der Grund, warum Sie kürzeren Code wie den moreThan20
schreiben können, den Sie oben gesehen haben:
let array = // ES5 wayvar moreThan20 = array.filter(function (num) { return num > 20})// ES6 waylet moreThan20 = array.filter(num => num > 20)
Zusammenfassend sind Pfeilfunktionen ziemlich cool. Sie brauchen ein wenig Zeit, um sich daran zu gewöhnen, also probieren Sie es aus und Sie werden es bald überall benutzen.
Aber bevor Sie auf den FTW-Zug der Pfeilfunktionen springen, möchte ich Sie über eine weitere wichtige Funktion der ES6-Pfeilfunktion informieren, die viel Verwirrung stiftet – die lexikalische this
.
Das lexikalische this
this
ist ein eindeutiges Schlüsselwort, dessen Wert sich je nach Aufruf ändert. Wenn es außerhalb einer Funktion aufgerufen wird, verwendet this
standardmäßig das Window
-Objekt im Browser.
console.log(this) // Window
Wenn this
in einem einfachen Funktionsaufruf aufgerufen wird, wird this
auf das globale Objekt gesetzt. Bei Browsern ist this
immer Window
.
function hello () { console.log(this)}hello() // Window
JavaScript setzt innerhalb eines einfachen Funktionsaufrufs immer this
auf das window Objekt. Dies erklärt, warum der Wert this
in Funktionen wie setTimeout
immer Window
ist.
Wenn this
in einer Objektmethode aufgerufen wird, wäre this
das Objekt selbst:
let o = { sayThis: function() { console.log(this) }}o.sayThis() // o
Wenn die Funktion als Konstruktor aufgerufen wird, bezieht sich this
auf das neu erstellte Objekt.
function Person (age) { this.age = age}let greg = new Person(22)let thomas = new Person(24)console.log(greg) // this.age = 22console.log(thomas) // this.age = 24
Bei Verwendung in einem Ereignis-Listener wird this
auf das Element gesetzt, das das Ereignis ausgelöst hat.
let button = document.querySelector('button')button.addEventListener('click', function() { console.log(this) // button})
Wie Sie in den obigen Situationen sehen können, wird der Wert von this
von der Funktion festgelegt, die ihn aufruft. Jede Funktion definiert ihren eigenen this
Wert.
In fetten Pfeilfunktionen wird this
niemals an einen neuen Wert gebunden, unabhängig davon, wie die Funktion aufgerufen wird. this
ist immer derselbe this
-Wert wie der umgebende Code. (Übrigens, Lexikalisch bedeutet in Bezug auf, was ich denke, ist, wie das lexikalische this
seinen Namen bekam).
Okay, das klingt verwirrend, also lassen Sie uns ein paar echte Beispiele durchgehen.
Erstens möchten Sie niemals Pfeilfunktionen verwenden, um Objektmethoden zu deklarieren, da Sie das Objekt nicht mehr mit this
referenzieren können.
let o = { // Don't do this notThis: () => { console.log(this) // Window this.objectThis() // Uncaught TypeError: this.objectThis is not a function }, // Do this objectThis: function () { console.log(this) // o } // Or this, which is a new shorthand objectThis2 () { console.log(this) // o }}
Zweitens möchten Sie möglicherweise keine Pfeilfunktionen zum Erstellen von Ereignis-Listenern verwenden, da this
nicht mehr an das Element gebunden ist, an das Sie Ihren Ereignis-Listener angehängt haben.
Sie können jedoch immer den richtigen this
Kontext mit event.currentTarget
. Deshalb sagte ich vielleicht nicht.
button.addEventListener('click', function () { console.log(this) // button})button.addEventListener('click', e => { console.log(this) // Window console.log(event.currentTarget) // button})
Drittens möchten Sie möglicherweise das lexikalische this
an Stellen verwenden, an denen sich die this
-Bindung ändert, ohne dass Sie dies möchten. Ein Beispiel ist die Timeout-Funktion, sodass Sie sich nie mit dem Unsinn this
, that
oder self
befassen müssen.
let o = { // Old way oldDoSthAfterThree: function () { let that = this setTimeout(function () { console.log(this) // Window console.log(that) // o }) }, // Arrow function way doSthAfterThree: function () { setTimeout(() => { console.log(this) // o }, 3000) }}
Dieser Anwendungsfall ist besonders hilfreich, wenn Sie nach einiger Zeit eine Klasse hinzufügen oder entfernen mussten:
let o = { button: document.querySelector('button') endAnimation: function () { this.button.classList.add('is-closing') setTimeout(() => { this.button.classList.remove('is-closing') this.button.classList.remove('is-open') }, 3000) }}
Schließlich können Sie die fat arrow-Funktion an einer anderen Stelle verwenden, um Ihren Code übersichtlicher und kürzer zu machen, wie im Beispiel moreThan20
, das wir oben hatten:
let array = let moreThan20 = array.filter(num => num > 20)
Lass uns weitermachen.
Standardparameter
Standardparameter in ES6 … nun, gibt uns eine Möglichkeit, Standardparameter anzugeben, wenn wir Funktionen definieren. Lassen Sie uns ein Beispiel durchgehen und Sie werden sehen, wie hilfreich es ist.
Angenommen, wir erstellen eine Funktion, die den Namen eines Spielers aus einem Team ankündigt. Wenn Sie diese Funktion in ES5 schreiben, ähnelt sie der folgenden:
function announcePlayer (firstName, lastName, teamName) { console.log(firstName + ' ' + lastName + ', ' + teamName)}announcePlayer('Stephen', 'Curry', 'Golden State Warriors')// Stephen Curry, Golden State Warriors
Auf den ersten Blick sieht dieser Code in Ordnung aus. Aber was wäre, wenn wir einen Spieler ankündigen müssten, der keinem Team angehört?
Der aktuelle Code schlägt peinlich fehl, wenn wir teamName
weggelassen haben:
announcePlayer('Zell', 'Liew')// Zell Liew, undefined
Ich bin mir ziemlich sicher, dass undefined kein Team ist 😉.
Wenn der Spieler nicht verbunden ist, wäre die Ankündigung von Zell Liew, unaffiliated
sinnvoller als Zell Liew, undefined
. Stimmst du nicht zu?
Um announcePlayer
Zell Liew, unaffiliated
anzukündigen, besteht eine Möglichkeit darin, die Zeichenfolge unaffiliated
als teamName
:
announcePlayer('Zell', 'Liew', 'unaffiliated')// Zell Liew, unaffiliated
Obwohl dies funktioniert, können wir es besser machen, indem wir unaffiliated
in announcePlayer
umgestalten, indem wir überprüfen, ob teamName
definiert ist.
In der ES5-Version können Sie den Code folgendermaßen umgestalten:
function announcePlayer (firstName, lastName, teamName) { if (!teamName) { teamName = 'unaffiliated' } console.log(firstName + ' ' + lastName + ', ' + teamName)}announcePlayer('Zell', 'Liew')// Zell Liew, unaffiliatedannouncePlayer('Stephen', 'Curry', 'Golden State Warriors')// Stephen Curry, Golden State Warriors
Oder, wenn Sie mit ternären Operatoren versierter sind, hätten Sie eine tersere Version wählen können:
function announcePlayer (firstName, lastName, teamName) { var team = teamName ? teamName : 'unaffiliated' console.log(firstName + ' ' + lastName + ', ' + team)}
In ES6 können wir mit Standardparametern ein Gleichheitszeichen (=
) hinzufügen, wenn wir einen Parameter definieren. Wenn wir dies tun, verwendet ES6 automatisch diesen Wert, wenn der Parameter nicht definiert ist.
Wenn also teamName
in diesem Code undefiniert ist, wird standardmäßig unaffiliated
:
const announcePlayer = (firstName, lastName, teamName = 'unaffiliated') => { console.log(firstName + ' ' + lastName + ', ' + teamName)}announcePlayer('Zell', 'Liew')// Zell Liew, unaffiliatedannouncePlayer('Stephen', 'Curry', 'Golden State Warriors')// Stephen Curry, Golden State Warriors
Ziemlich cool, nicht wahr? 🙂
Noch eine Sache. Wenn Sie den Standardwert aufrufen möchten, können Sie undefined
manuell übergeben. Diese manuelle Übergabe von undefined
hilft, wenn Ihr Standardparameter nicht das letzte Argument einer Funktion ist.
announcePlayer('Zell', 'Liew', undefined)// Zell Liew, unaffiliated
Das ist alles, was Sie über Standardparameter wissen müssen. Es ist einfach und sehr nützlich 🙂
Destrukturierung
Destrukturierung ist eine bequeme Möglichkeit, Werte aus Arrays und Objekten abzurufen. Es gibt geringfügige Unterschiede zwischen der Destrukturierung von Arrays und Objekten.
Destrukturierung von Objekten
Angenommen, Sie haben das folgende Objekt:
const Zell = { firstName: 'Zell', lastName: 'Liew'}
Um firstName
und lastName
von Zell
zu erhalten, mussten Sie zwei Variablen erstellen und dann jede Variable einem Wert zuweisen, wie folgt:
let firstName = Zell.firstName // Zelllet lastName = Zell.lastName // Liew
Mit Destrukturierung können Sie diese Variablen mit einer einzigen Codezeile erstellen und zuweisen. So zerstören Sie Objekte:
let { firstName, lastName } = Zellconsole.log(firstName) // Zellconsole.log(lastName) // Liew
Sehen Sie, was hier passiert ist? Indem wir beim Deklarieren von Variablen geschweifte Klammern ({}
) hinzufügen, weisen wir JavaScript an, die oben genannten Variablen zu erstellen und dann Zell.firstName
firstName
bzw. Zell.lastName
lastName
zuzuweisen.
Das passiert unter der Haube:
// What you writelet { firstName, lastName } = Zell// ES6 does this automaticallylet firstName = Zell.firstNamelet lastName = Zell.lastName
Wenn nun bereits ein Variablenname verwendet wird, können wir die Variable nicht erneut deklarieren (insbesondere wenn Sie let
oder const
).
Folgendes funktioniert nicht:
let name = 'Zell Liew'let course = { name: 'JS Fundamentals for Frontend Developers' // ... other properties}let { name } = course // Uncaught SyntaxError: Identifier 'name' has already been declared
Wenn Sie auf Situationen wie die oben genannten stoßen, können Sie Variablen umbenennen, während Sie mit einem Doppelpunkt destrukturieren (:
).
In diesem Beispiel unten erstelle ich eine Variable courseName
und weise ihr course.name
zu.
let { name: courseName } = courseconsole.log(courseName) // JS Fundamentals for Frontend Developers// What ES6 does under the hood:let courseName = course.name
Noch eine Sache.
Machen Sie sich keine Sorgen, wenn Sie versuchen, eine Variable zu zerstören, die nicht in einem Objekt enthalten ist. Es wird nur undefined
zurückgegeben.
let course = { name: 'JS Fundamentals for Frontend Developers'}let { package } = courseconsole.log(package) // undefined
Aber warte, das ist noch nicht alles. Erinnern Sie sich an die Standardparameter?
Sie können auch Standardparameter für Ihre destrukturierten Variablen schreiben. Die Syntax ist dieselbe wie beim Definieren von Funktionen.
let course = { name: 'JS Fundamentals for Frontend Developers'}let { package = 'full course' } = courseconsole.log(package) // full course
Sie können sogar Variablen umbenennen, während Sie Standardwerte angeben. Kombinieren Sie einfach die beiden. Es wird am Anfang ein bisschen lustig aussehen, aber Sie werden sich daran gewöhnen, wenn Sie es oft verwenden:
let course = { name: 'JS Fundamentals for Frontend Developers'}let { package: packageName = 'full course' } = courseconsole.log(packageName) // full course
Das war’s für die Destrukturierung von Objekten. Lassen Sie uns weitermachen und über die Destrukturierung von Arrays sprechen 😄.
Destrukturierende Arrays
Destrukturierende Arrays und Destrukturobjekte sind ähnlich. Wir verwenden eckige Klammern () anstelle von geschweiften Klammern (
{}
).
Wenn Sie ein Array zerstören,
- Ihre erste Variable ist das erste Element im Array.
- Ihre zweite Variable ist das zweite Element im Array.
- und so weiter…
let = console.log(one) // 1console.log(two) // 2
Es ist möglich, so viele Variablen zu zerstören, dass Sie die Anzahl der Elemente im angegebenen Array überschreiten. Wenn dies geschieht, ist die zusätzliche destrukturierte Variable nur undefined
.
let = console.log(one) // 1console.log(two) // 2console.log(three) // undefined
Beim Destrukturieren von Arrays destrukturieren wir oft nur die Variablen, die wir benötigen. Wenn Sie den Rest des Arrays benötigen, können Sie den Rest-Operator (...
) wie folgt verwenden:
let scores = let = scoresconsole.log(first) // 98console.log(second) // 95console.log(third) // 93console.log(rest) //
Wir werden im folgenden Abschnitt mehr über Rest-Operatoren sprechen. Aber lassen Sie uns jetzt über eine einzigartige Fähigkeit sprechen, die Sie mit destrukturierten Arrays erhalten – Variablen austauschen.
Variablen mit destrukturierten Arrays austauschen
Angenommen, Sie haben zwei Variablen, a
und b
.
let a = 2let b = 3
Sie wollten diese Variablen austauschen. Also a = 3
und b = 2
. In ES5 müssen Sie eine temporäre dritte Variable verwenden, um den Swap abzuschließen:
let a = 2let b = 3let temp// swappingtemp = a // temp is now 2a = b // a is now 3b = temp // b is now 2
Obwohl dies funktioniert, kann die Logik unscharf und verwirrend sein, insbesondere bei der Einführung einer dritten Variablen.
Sehen Sie sich nun an, wie Sie es mit destrukturierten Arrays auf ES6-Weise tun:
let a = 2let b = 3; // semicolon required because next line begins with a square bracket// Swapping with destructured arrays = console.log(a) // 3console.log(b) // 2
💥💥💥. So viel einfacher im Vergleich zur vorherigen Methode zum Austauschen von Variablen! 🙂
Als nächstes sprechen wir über die Destrukturierung von Arrays und Objekten in einer Funktion.
Destrukturierung von Arrays und Objekten beim Deklarieren von Funktionen
Das Coolste an der Destrukturierung ist, dass Sie sie überall verwenden können. Buchstäblich. Sie können sogar Objekte und Arrays in Funktionen zerstören.
Angenommen, wir haben eine Funktion, die ein Array von Scores aufnimmt und ein Objekt mit den drei besten Scores zurückgibt. Diese Funktion ähnelt dem, was wir beim Destrukturieren von Arrays getan haben.
// Note: You don't need arrow functions to use any other ES6 featuresfunction topThree (scores) { let = scores return { first: first, second: second, third: third }}
Eine alternative Möglichkeit, diese Funktion zu schreiben, besteht darin, scores
zu zerstören, während die Funktion deklariert wird. In diesem Fall muss eine Codezeile weniger geschrieben werden. Gleichzeitig wissen wir, dass wir ein Array aufnehmen.
function topThree () { return { first: first, second: second, third: third }}
Super cool, nicht wahr? 😄.
Nun, hier ist ein kurzes kleines Quiz für Sie. Da wir Standardparameter und Destrukturierung beim Deklarieren von Funktionen kombinieren können, was sagt das Folgende?
function sayMyName ({ firstName = 'Zell', lastName = 'Liew'} = {}) { console.log(firstName + ' ' + lastName)}
Dies ist eine schwierige Frage. Wir kombinieren einige Funktionen miteinander.
Zuerst können wir sehen, dass diese Funktion ein Argument, ein Objekt, aufnimmt. Dieses Objekt ist optional und standardmäßig {}
, wenn es nicht definiert ist.
Zweitens versuchen wir, firstName
und lastName
Variablen aus dem angegebenen Objekt zu zerstören. Wenn diese Eigenschaften gefunden werden, verwenden Sie sie.
Wenn firstName
oder lastName
im angegebenen Objekt undefiniert ist, setzen wir es auf Zell
bzw. Liew
.
Diese Funktion liefert also die folgenden Ergebnisse:
sayMyName() // Zell LiewsayMyName({firstName: 'Zell'}) // Zell LiewsayMyName({firstName: 'Vincy', lastName: 'Zhang'}) // Vincy Zhang
Ziemlich cool, Destrukturierung und Standardparameter in einer Funktionsdeklaration zu kombinieren, oder? 😄. Ich liebe das.
Als nächstes schauen wir uns rest and spread an.
Der Rest-Parameter und der Spread-Operator
Der Rest-Parameter und der Spread-Operator sehen gleich aus. Sie sind beide mit drei Punkten gekennzeichnet (...
).
Was sie tun, ist unterschiedlich, je nachdem, wofür sie verwendet werden. Deshalb werden sie anders benannt. Schauen wir uns also den Rest-Parameter und den Spread-Operator separat an.
Der Rest-Parameter
Frei übersetzt bedeutet der Rest-Parameter, dass Sie den Rest des Materials in ein Array packen. Es konvertiert eine durch Kommas getrennte Liste von Argumenten in ein Array.
Schauen wir uns den Rest-Parameter in Aktion an. Stellen Sie sich vor, wir haben eine Funktion add
, die ihre Argumente zusammenfasst:
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) // 55
In ES5 waren wir immer dann von der Variablen arguments
abhängig, wenn wir uns mit einer Funktion befassen mussten, die eine unbekannte Anzahl von Variablen aufnimmt. Diese arguments
Variable ist ein Array-ähnliches Symbol
.
function sum () { console.log(arguments)}sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Eine Möglichkeit, diese Summe von Argumenten zu berechnen, besteht darin, sie in ein Array mit Array.prototype.slice.call(arguments)
zu konvertieren und dann jede Zahl mit einer Array-Methode wie forEach
oder reduce
zu durchlaufen.
Ich bin sicher, Sie können forEach
alleine machen, also hier ist das reduce
Beispiel:
// ES5 wayfunction sum () { let argsArray = Array.prototype.slice.call(arguments) return argsArray.reduce(function(sum, current) { return sum + current }, 0)}
Mit dem ES6-Rest-Parameter könnten wir alle durch Kommas getrennten Argumente direkt in ein Array packen.
// ES6 wayconst sum = (...args) => args.reduce((sum, current) => sum + current, 0)// ES6 way if we didn't shortcut it with so many arrow functionsfunction sum (...args) { return args.reduce((sum, current) => sum + current, 0)}
Viel sauberer? 🙂.
Nun haben wir den Rest-Parameter zuvor im Abschnitt Destrukturierung kurz angesprochen. Dort haben wir versucht, eine Reihe von Partituren in die drei besten Partituren zu zerlegen:
let scores = let = scoresconsole.log(first) // 98console.log(second) // 95console.log(third) // 93
Wenn wir den Rest der Partituren wollten, könnten wir dies tun, indem wir den Rest der Partituren in ein Array mit dem Rest-Parameter packen.
let scores = let = scoresconsole.log(restOfScores) //
Wenn Sie jemals verwirrt sind, denken Sie daran — der rest-Parameter packt alles in ein Array. Es erscheint in Funktionsparametern und beim Destrukturieren von Arrays.
Als nächstes gehen wir weiter zu verbreiten.
Der Spread-Operator
Der Spread-Operator verhält sich im Vergleich zum Rest-Parameter umgekehrt. Locker gesagt, es nimmt ein Array und verteilt es (wie jam) in eine durch Kommas getrennte Liste von Argumenten.
let array = // These two are exactly the sameconsole.log(...array) // one two threeconsole.log('one', 'two', 'three') // one two three
Der Spread-Operator wird häufig verwendet, um Arrays auf eine Weise zu verketten, die einfacher zu lesen und zu verstehen ist.
Angenommen, Sie wollten die folgenden Arrays verketten:
let array1 = let array2 = let array3 =
Die ES5-Methode zum Verketten dieser beiden Arrays besteht in der Verwendung der Methode Array.concat
. Sie können mehrere Array.concat
verketten, um eine beliebige Anzahl von Arrays wie folgt zu verketten:
// ES5 waylet combinedArray = array1.concat(array2).concat(array3)console.log(combinedArray) //
Mit dem ES6 Spread Operator können Sie die Arrays in ein neues Array wie dieses verteilen, das etwas einfacher zu lesen ist, sobald Sie sich daran gewöhnt haben:
// ES6 waylet combinedArray = console.log(combinedArray) //
Der Spread-Operator kann auch verwendet werden, um ein Element aus einem Array zu entfernen, ohne das Array zu mutieren. Diese Methode wird häufig in Redux verwendet. Ich empfehle Ihnen dringend, sich dieses Video von Dan Abramov anzusehen, wenn Sie sehen möchten, wie es funktioniert.
Das war’s sicher 🙂
Erweiterte Objektliterale
Objekte sollten Ihnen vertraut sein, da Sie JavaScript schreiben. Nur für den Fall, dass Sie nichts über sie wissen, sehen sie ungefähr so aus:
const anObject = { property1: 'value1', property2: 'value2', property3: 'value3',}
ES6 enhanced object Literals bringt drei süße Upgrades auf die Objekte, die Sie kennen und lieben. Sie sind:
- Eigenschaftswert Shorthands
- Method shorthands
- Die Möglichkeit, berechnete Eigenschaftsnamen zu verwenden
Schauen wir uns jeden einzelnen an. Ich verspreche, das wird schnell gehen 🙂
Eigenschaftswert-Abkürzungen
Haben Sie bemerkt, dass Sie manchmal eine Variable zuweisen, die denselben Namen wie eine Objekteigenschaft hat? Weißt du, so etwas:
const fullName = 'Zell Liew'const Zell = { fullName: fullName}
Nun, würden Sie sich nicht wünschen, Sie könnten dies kürzer schreiben, da die Eigenschaft (fullName
) und der Wert (fullName
)?
(Oh du verwöhntes Gör 😝).
Hier sind die guten Nachrichten. Du kannst! 🙂
ES6 erweitert Objekte mit Eigenschaftswert-Abkürzungen. Dies bedeutet: Sie können die Variable nur schreiben, wenn Ihr Variablenname mit Ihrem Eigenschaftsnamen übereinstimmt. ES6 kümmert sich um den Rest.
So sieht es aus:
const fullName = 'Zell Liew'// ES6 wayconst Zell = { fullName}// Underneath the hood, ES6 does this:const Zell = { fullName: fullName}
Ziemlich ordentlich, was? Jetzt haben wir weniger Worte zu schreiben, und wir gehen alle glücklich nach Hause.
Während ich tanze, Bitte mach weiter und bewege dich zu mehr Kurzschriftgüte. Ich komme gleich zu dir.
Method shorthands
Methoden sind Funktionen, die einer Eigenschaft zugeordnet sind. Sie werden nur speziell benannt, weil sie Funktionen sind 🙂
Dies ist ein Beispiel für eine Methode:
const anObject = { aMethod: function () { console.log("I'm a method!~~")}}
Mit ES6 können wir Methoden mit einer Abkürzung schreiben. Wir können : function
aus einer Methodendeklaration entfernen und es funktioniert wie früher:
const anObject = { // ES6 way aShorthandMethod (arg1, arg2) {}, // ES5 way aLonghandMethod: function (arg1, arg2) {},}
Mit diesem Upgrade erhalten Objekte bereits eine Shorthand-Methode, also verwenden Sie bitte keine Pfeilfunktionen, wenn Sie Objekte definieren. Sie brechen den Kontext this
(siehe Pfeilfunktionen, wenn Sie sich nicht erinnern können, warum).
const dontDoThis = { // Noooo. Don't do this arrowFunction: () => {}}
Das war’s mit Objektmethoden-Abkürzungen. Gehen wir zum endgültigen Upgrade über, das wir für Objekte erhalten.
Berechnete Objekteigenschaftsnamen
Manchmal benötigen Sie einen dynamischen Eigenschaftsnamen, wenn Sie Objekte erstellen. Auf die alte JavaScript-Weise müssten Sie das Objekt erstellen und dann Ihre Eigenschaft in wie folgt zuweisen:
// ES5const newPropertyName = 'smile'// Create an object firstconst anObject = { aProperty: 'a value' }// Then assign the propertyanObject = ':D'// Adding a slightly different property and assigning itanObject = 'XD'// Result// {// aProperty: 'a value',// 'bigger smile': 'XD'// smile: ':D',// }
In ES6 müssen Sie diesen Umweg nicht mehr ausführen. Sie können dynamische Eigenschaftsnamen direkt beim Erstellen Ihres Objekts zuweisen. Der Schlüssel besteht darin, die dynamische Eigenschaft in eckige Klammern zu setzen:
const newPropertyName = 'smile'// ES6 way.const anObject = { aProperty: 'a value', // Dynamic property names! : ':D', : 'XD',}// Result// {// aProperty: 'a value',// 'bigger smile': 'XD'// smile: ':D',// }
Schweeet! Nicht wahr? 🙂
Und das war’s für erweiterte Objektliterale. Hab ich nicht gesagt, es wird schnell gehen? 🙂
Kommen wir zu einem weiteren großartigen Feature, das ich absolut liebe: Template literals .
Template-Literale
Der Umgang mit Zeichenfolgen in JavaScript ist äußerst umständlich. Sie haben es selbst erlebt, als wir die Funktion announcePlayer
zuvor in Standardparametern erstellt haben. Dort haben wir Leerzeichen mit leeren Zeichenfolgen erstellt und sie mit Pluspunkten verbunden:
function announcePlayer (firstName, lastName, teamName) { console.log(firstName + ' ' + lastName + ', ' + teamName)}
In ES6 verschwindet dieses Problem dank Vorlagenliteralen! (In der Spezifikation wurden sie zuvor als Vorlagenzeichenfolgen bezeichnet).
Um ein Vorlagenliteral in ES6 zu erstellen, schließen Sie Zeichenfolgen mit Backticks ein (`
). Innerhalb von Backticks erhalten Sie Zugriff auf einen speziellen Platzhalter (${}
), in dem Sie JavaScript normal verwenden können.
So sieht es in Aktion aus:
const firstName = 'Zell'const lastName = 'Liew'const teamName = 'unaffiliated'const theString = `${firstName} ${lastName}, ${teamName}`console.log(theString)// Zell Liew, unaffiliated
Siehst du das? Wir können alles mit Vorlagenliteralen gruppieren! Innerhalb von Template-Literalen ist es normal Englisch. Fast so, als würden wir eine Template-Engine verwenden 🙂
Das Beste an Template-Literalen ist, dass Sie problemlos mehrzeilige Zeichenfolgen erstellen können. Dies funktioniert sofort:
const multi = `One upon a time,In a land far far away,there lived a witich,who could change night into day`
Ein netter Trick besteht darin, diese Zeichenfolgen zu verwenden, um HTML-Elemente in JavaScript zu erstellen, wenn Sie sie benötigen. (Hinweis: Dies ist möglicherweise nicht der beste Weg, um HTML-Elemente zu erstellen, aber es ist immer noch viel besser, als sie einzeln zu erstellen!).
const container = document.createElement('div')const aListOfItems = `<ul> <li>Point number one</li> <li>Point number two</li> <li>Point number three</li> <li>Point number four</li> </ul>`container.innerHTML = aListOfItemsdocument.body.append(container)
Siehe den Stift Verwenden von mehrzeiligen Zeichenfolgen zum Erstellen komplizierterer HTML-Elemente von Zell Liew (@zellwk) auf CodePen.
Ein weiteres Merkmal von Vorlagenliteralen werden Tags genannt. Tags sind Funktionen, mit denen Sie das Vorlagenliteral bearbeiten können, wenn Sie eine beliebige Zeichenfolge ersetzen möchten.
So sieht es aus:
const animal = 'lamb'// This a tagconst tagFunction = () => { // Do something here}// This tagFunction allows you to manipulate the template literal.const string = tagFunction `Mary had a little ${animal}`
Um ehrlich zu sein, obwohl Template-Tags cool aussehen, hatte ich noch keinen Anwendungsfall für sie. Wenn Sie mehr über Vorlagen-Tags erfahren möchten, empfehlen wir Ihnen, diese Referenz zu MDN zu lesen.
Das war’s für Template-Literale.
Einpacken
Woo! Das sind fast alle fantastischen ES6-Funktionen, die ich regelmäßig verwende. ES6 ist großartig. Es lohnt sich auf jeden Fall, sich ein wenig Zeit zu nehmen und mehr über sie zu erfahren, damit Sie verstehen können, worüber alle anderen schreiben.