Ist es Spread “Syntax” oder der Spread “Operator”?

Lesezeit: 9 Minuten

Ich habe gehört ... beides als „Spread“ bezeichnet Syntax“ und „die Ausbreitung Operator“, wobei letzteres viel beliebter ist. Die URL der relevanten MDN-Dokumentation deutet darauf hin, dass es ursprünglich als Ausbreitung bezeichnet wurde Operator aber später in Spread-Syntax geändert, und Liste der Betreiber von MDN erwähnt es nicht.

Google scheint den Begriff vorzuschlagen Operator ist beliebter und akzeptierter, mit Websites wie der Microsoft-Dokumentation und es6-features.org als solche bezeichnen.

Welcher Begriff wäre im Zusammenhang mit ECMAScript der richtige, wenn überhaupt, und warum? Was ist mit der Array-Destrukturierungszuweisung?

Es ist kein Operator.

Im wahrsten Sinne des Wortes ist es keiner. Es war seit seiner Einführung ein großes Missverständnis und trotz der weit verbreiteten Meinung – es ist keines, und es gibt ein paar objektive Punkte, die angemerkt werden müssen:

  • Es passt nicht zur Definition eines Operators
  • Es kann nicht als Operator verwendet werden
  • Die Sprachspezifikation impliziert, dass es sich nicht um einen Operator handelt

Es sollte erwähnt werden, dass die Spread-Syntax in verschiedenen „Geschmacksrichtungen“ vorkommt, in verschiedenen Kontexten verwendet wird und häufig mit unterschiedlichen Namen bezeichnet wird, während dasselbe Zeichen verwendet wird. Spread-Syntax ist im Grunde ein Überbegriff für die Anwendung der ... Interpunktionszeichen, und sehen Sie sich die großartige Antwort von Felix Kling an, in der alle Verwendungen und Namen aufgeführt sind. Weitere Erläuterungen zu den Verwendungen dieser Personen finden Sie in der ergänzenden Antwort.

Was ist ein Operator?

Semantisch sind Operatoren im Kontext von ECMAScript nur eingebaute Funktionen, die Argumente aufnehmen und zu a auswerten Einzelwert — geschrieben in Präfix-, Infix- oder Postfix-Notation und normalerweise mit symbolischen Namen wie z + oder /. Von Wikipedia:

Einfach ausgedrückt wird ein Ausdruck, der einen Operator enthält, auf irgendeine Weise ausgewertet, und der resultierende Wert kann nur ein Wert (ein R-Wert) oder ein Objekt sein, das eine Zuweisung ermöglicht (ein L-Wert).

Zum Beispiel die + -Operator ergibt einen Wert wie z. B. 2, was ein Ausdruck auf der rechten Seite ist, und der . -Operator führt zu einem Objekt, das eine Zuweisung ermöglicht, z foo.barein Ausdruck auf der linken Seite.

An der Oberfläche, die ... Satzzeichen1 sieht aus wie ein unärer Präfixoperator:

const baz = [foo, ...bar];

Aber das Problem mit diesem Argument ist das ...bar wird nicht zu einem singulären Wert ausgewertet; es verbreitet das Iterierbare bar‘s Elemente, eins nach dem anderen. Dasselbe gilt für Spread-Argumente:

foo(...bar);

Hier, foo erhält trennen Argumente aus dem Iterable bar. Sie sind separate Werte, an die übergeben wird foo, nicht nur ein Wert. Es passt nicht zur Definition eines Operators, also ist es keiner.

Warum ist es kein Operator?

Ein weiterer Punkt ist, dass Operatoren eigenständig sein und einen einzelnen Wert zurückgeben sollen. Zum Beispiel:

const bar = [...foo];

Wie bereits erwähnt, funktioniert das gut. Das Problem tritt auf, wenn Sie dies versuchen:

const bar = ...foo;

Wenn die Spread-Syntax ein Operator wäre, würde letzteres gut funktionieren da Operatoren den Ausdruck zu einem einzelnen Wert auswerten aber Ausbreitung nicht, also schlägt es fehl. Spread-Syntax und Spread-Argumente funktionieren nur im Kontext von Arrays und Funktionsaufrufen, da diese Strukturen mehrere Werte erhalten, die von Spreading-Array-Elementen oder -Argumenten bereitgestellt werden. Das Auswerten mehrerer Werte liegt außerhalb der Möglichkeiten eines Operators.

Was sagen die Normen?

Die vollständige Liste der Betreiber ist in den Abschnitten §12.5 bis §12.15 im aufgeführt ECMAScript 2015 Sprachspezifikationdie Spezifikation, in der ... eingeführt wird, was nicht erwähnt wird .... Es kann auch gefolgert werden, dass es sich nicht um einen Operator handelt. Die beiden Hauptfälle, die in dieser Antwort erwähnt werden, in denen Spread-Syntax in einer Produktion ist, für Funktionsaufrufe (Spread-Argumente) oder Array-Literale (Spread-Syntax) werden nachfolgend beschrieben:

ArrayLiteral :
  [ Elisionopt ]
  [ ElementList ]
  [ ElementList , Elisionopt ]

ElementList :
  Elisionopt AssignmentExpression
  Elisionopt SpreadElement
  ElementList , Elisionopt AssignmentExpression
  ElementList , Elisionopt SpreadElement

Elision :
  ,
  Elision ,

SpreadElement :
  ... AssignmentExpression
  

Und für Funktionsaufrufe:

CallExpression :
  MemberExpression Arguments

Arguments :
  ( )
  ( ArgumentList )

ArgumentList :
  AssignmentExpression
  ... AssignmentExpression
  ArgumentList , AssignmentExpression
  ArgumentList , ... AssignmentExpression
  

Bei diesen Produktionen kann man den Schluss ziehen, dass der Spread-„Operator“ nicht existiert. Wie bereits erwähnt, sollten Operatoren eigenständig sein, wie in const bar = ...foo und zu einem einzigen Wert auswerten. Die Syntax der Sprache verhindert dies, was bedeutet, dass Spread-Syntax nie als Standalone gedacht war. Es ist eine Erweiterung für Array-Initialisierer und Funktionsaufrufeeine Erweiterung ihrer Grammatik.

Warum ‘Syntax’ verbreiten?

Syntax, wie definiert durch Wikipedia:

In der Informatik ist die Syntax einer Computersprache der Satz von Regeln, die die Kombinationen von Symbolen definieren, die in dieser Sprache als korrekt strukturiertes Dokument oder Fragment angesehen werden.

Syntax ist im Grunde die „Form“ der Sprache, Regeln, die festlegen, was legal ist oder nicht, wie der Code aussehen soll und wie der Code geschrieben werden soll. In diesem Fall definiert die Grammatik von ECMAScript speziell die ... Zeichensetzungszeichen nur in Funktionsaufrufen und Array-Literalen als Erweiterung erscheinen – was eine Regel ist, die eine Kombination von Symbolen definiert (...foo), die zusammen als legal angesehen werden, also ist es so Syntax ähnlich wie eine Pfeilfunktion (=>) ist kein Operator, sondern eine Syntax2.

Berufung ... ein Operator ist eine Fehlbezeichnung. Ein Operator ist eine eingebaute Funktion, die Argumente (Operanden) aufnimmt und in Form einer Präfix-, Infix- oder Postfix-Notation vorliegt und wertet genau einen Wert aus. ...erfüllt zwar die ersten beiden Bedingungen, aber nicht die letzte. ..., ist stattdessen Syntax, weil sie spezifisch und explizit in der Grammatik der Sprache definiert ist. Daher wird „der Spread-Operator“ objektiv korrekter als „Spread-Syntax“ bezeichnet.


1 Der Begriff „Interpunktionszeichen“ bezieht sich auf Satzzeichen in ECMAScript 2015 und spätere Spezifikationen. Diese Symbole enthalten Syntaxkomponenten und Operatoren und sind Punktatoren der Sprache. ... ist selbst ein Zeichensetzungszeichen, aber der Begriff „gespreizte Syntax“ bezieht sich auf die gesamte Anwendung des Zeichensetzungszeichens.

2 => selbst ist ein Satzzeichengenauso wie ... aber worauf ich mich speziell beziehe ist Syntax der Pfeilfunktiondie Anwendung des => Satzzeichen ((…) => { … }), genauso wie Spread-Syntax bezieht sich auf die Anwendung der ... Satzzeichen.

  • Upvoted für die Forschung. Fragen Sie sich immer noch, warum das wichtig ist? Wenn es umgangssprachlich bereits als „Spread-Operator“ bekannt ist, bezweifle ich, dass irgendjemand missverstehen wird, was in einem Gespräch gemeint ist.

    – Patrick Roberts

    5. Juli 2017 um 19:56 Uhr

  • @PatrickRoberts Du hast Recht, aber ich wollte eine Unterscheidung treffen. Das größte Problem für mich war, dass es keinen einzigen maßgeblichen Beitrag gab, der eine sichere Antwort auf die Frage gab, und die Frage ergab sich daraus, warum MDN eine Syntax hatte, während alle anderen einen Operator hatten. Ich wollte nur mein Wissen teilen, aber auch den Unterschied zeigen.

    – Andreas Li

    5. Juli 2017 um 19:58 Uhr

  • @PatrickRoberts Nehmen wir an, der eine steht kurz davor, als JS-Grammatik-Nazi Karriere zu machen, weiß aber immer noch nicht, ob er / sie Leute bestrafen sollte, die “Spread Operator” sagen. Diese Antwort bietet eine sehr gute Erklärung.

    – Estus-Kolben

    5. Juli 2017 um 20:09 Uhr

  • Für mich, ... ist ein Interpunktionszeichen, das in Spread-Syntax und Rest-Parametern verwendet wird, es ist weder ein Operator noch eine Syntax für sich. Es ist äquivalent zu anderen Interpunktionszeichen wie ,, ; und : die in benannten Teilen der Grammatik (Parameterlisten, Anweisungen, Objektliterale) verwendet werden, aber nicht “Operatoren” genannt werden. Außerdem ist die neueste Version der Spezifikation ECMAScript 2017ich schätze, Sie haben 2015 zitiert, da das der Ort ist ... wurde vorgestellt. Schließlich erwähnen §12.5 bis 12.6 alle Operatoren und ... ist keiner von ihnen. Tut mir leid, ich kann Ihnen nur eine Stimme geben – stimmen Sie für Ihre Bemühungen ab. 😉

    – RobG

    6. Juli 2017 um 1:09 Uhr

  • @RobG Ja, ich habe die 6. Ausgabe zitiert, weil sie damals eingeführt wurde. Ich werde darauf achten, zu bearbeiten und zu erwähnen, dass alle Operatoren erwähnt werden, oder Sie könnten dies tun, wenn Sie möchten.

    – Andreas Li

    6. Juli 2017 um 1:11 Uhr


Andere Verwendungen der Syntax

Es gibt weitere zahlreiche Verwendungen der Spread/Rest-Syntax, die in der Hauptantwort nicht behandelt werden. Sie beinhalten:

  • Rest-Syntax in Funktionsparametern
  • Array und Objekt1 destrukturierende Aufgabe
  • Objektverbreitungssyntax in Objektliteralen1

Rest-Syntax

Eine Verwendung für Spread-Syntax, allgemein bezeichnet als sich ausruhen Syntax, wird für eine variable Anzahl von Argumenten in einer Funktion verwendet Argumente. Dies unterscheidet sich von Spread-Argumenten, die verwendet werden, um Argumente an eine Funktion zu übergeben Anruf basierend auf den Elementen einer Iterable. Zum Beispiel:

function add(...addends) {
  …
}

Hier wird Rest-Syntax für die Funktion verwendet add die zu erhalten sich ausruhen der Argumente im Bezeichner addends. Dies scheint einen singulären Wert als zu bewerten addends ist ein Array der übergebenen Argumente, aber was wäre, wenn wir es versuchen würden:

function foo(...[bar, baz]) {
  …
}

Hier, bar und baz würde beiden ein Wert zugewiesen, der dem ersten und dem zweiten übergebenen Argument entspricht – daher wird dies nicht immer zu einem Wert ausgewertet. Das zugrunde liegende Problem ist das ...addends im ersten Beispiel und ...[bar, baz] im zweiten wird überhaupt kein Wert ausgewertet – es wird nur während der Operation verwendet, ein Array der Argumente dem Bezeichner zuzuweisen. Daher ist es eine Syntax, eine variable Anzahl von Argumenten für eine Funktion zuzulassen, nicht für einen Operator.

Destrukturierende Aufgabe

Spread-Syntax kann auch während verwendet werden Array-Destrukturierungszuweisung und wird in der Sprachspezifikation tatsächlich als rest-Element bezeichnet (weil es bei der Verwendung in der Destrukturierung wird der Rest des destrukturierten Iterable). Ein überzeugendes Argument kann vorgebracht werden, da dies wie ein Operator erscheint:

const [...bar] = [1, 2, 3];

Es wird wie ein unärer Präfixoperator verwendet. Hier, bar wertet zu[1, 2, 3]– das ist ein einzelner Wert. Aber das passiert nicht immer, zum Beispiel:

const [first, ...[second, third]] = [1, 2, 3];

Hier, first, secondund third mit 1, 2 bzw. 3 bewerten. Aber ...[second, third] weist zwei Bezeichnern zu, nicht einem, und wertet keinen singulären Wert aus, sondern zwei. Genau wie bei der Rest-Syntax besteht das zugrunde liegende Problem darin ...bar im ersten Beispiel und ...[second, third] in dieser Sekunde wertet überhaupt keinen Wert aus — es wird nur während der Zuweisung verwendet. Es ist also überhaupt kein Operator2nur eine neue Syntax, um beim Entpacken von Werten zu helfen.

Objektverbreitungssyntax

Eine letzte Verwendung für die Spread-Syntax sind Objektliterale, die allgemein als “Objekt-Spread-Eigenschaften” bezeichnet werden, in denen die eigenen aufzählbaren Eigenschaften eines Zielobjekts auf ein anderes verteilt werden, zum Beispiel:

const foo = { ...bar };

Dies ist kein Operator, genau wie die Array-Spread-Syntax kein Operator ist. Das Konzept ist dasselbe, anstelle von Indizes und Elementen in Arrays, barDie aufzählbaren Schlüssel und Werte von werden verteilt auf foo. Hier ein Sammlung von barDie Eigenschaften von sind verteilt – nicht nur ein einzelner Wert, daher passt es nicht zur Definition eines Operators.


1 Objekt Rest/Spread-Eigenschaften befinden sich derzeit im Vorschlag für Stufe 3 für ECMAScript und werden sehr wahrscheinlich in naher Zukunft hinzugefügt

2 Ein weiteres Problem bei der Destrukturierung von Zuweisungen als Operator, abgesehen von der Semantik, ist folgendes die Sprachspezifikation definiert es als ergänzende Syntax — kein ergänzender Operator, und das zu Recht. Es ist nicht eigenständig, da dies nicht funktioniert:

const ...bar = [1, 2, 3, 4];

Es ist kontextbezogen und nur erlaubt durch die Grammatik der Sprache, Objektliterale und Array-Literale, die Ausdrücke auf der linken Seite sind. Das ist auch Grammatik verfeinert die Interpretation eines Ausdrucks auf der linken Seite. Auch dies ist eine Erweiterung, die neu hinzugefügt werden soll Syntax zur Sprache, eine Verfeinerung der bestehenden Grammatik. Das bekräftigt das Argument mit der Spezifikation.

914480cookie-checkIst es Spread “Syntax” oder der Spread “Operator”?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy