Warum gibt es keine zusammengesetzten Zuweisungsoperatoren für logische Operatoren (wie ||, && etc)?


20

Gemäß ECMA-262, Teil 11,13, folgende ist die erschöpfende Liste von Verbindung Zuweisungsoperator: *= /= %= += -= <<= >>= >>>= &= ^= |=.

Nach dem Teil 11.11 var c = a || bwird der aWert in cif gesetzt , wenn er ToBoolean(a)wahr ist, und wird der bWert in celse gesetzt. Daher wird das logische ODER häufig als Vereinigungsoperator verwendet, z

function (options) {
    options = options || {};
}

Häufig genug, coalesce wird verwendet , um den Standardwert für die Variable angeben, wie oben gezeigt wurde: a = a || b.

Es scheint , dass die Verbindung Zuweisungsoperator ||=wäre wirklich nützlich sein, so dass der Code oben in einer kürzeren und sauberere Art und Weise schreiben: a ||= b. Allerdings ist es nicht , dass es (obwohl *=, +=und andere zusammengesetzte Zuweisungsoperatoren sind).

Die Frage ist, warum?


2
Ich bin unglaublich ratlos, dass der Operator% = überhaupt existiert. Wer hat entschieden, dass das notwendig ist? Einige dieser Operatoren scheinen falsche Entscheidungen für das Sprachdesign zu treffen.
Jonathan Rich

2
@ JonathanRich: warum nicht% =? Wenn Sie einen dieser Zuweisungsoperatoren haben, werden sich einige Entwickler (wie penartur) früher oder später fragen, warum Operatoren "gleichwertiger" sind als andere.
Kevin Cline

4
@JonathanRich Crypto nutzt das Modul in erheblichem Maße. Außerdem gibt es eine gewünschte Orthogonalität mit dem Rest der Arithmetik zu arithmetischen Zuweisungsoperator (wenn man erwartet +=, *=, -=, /=, warum nicht %=funktioniert?).

4
@JonathanRich: Der Operator ist nützlich, wenn Sie etwas Zirkulares haben und es normalisieren möchten, z. B. angle %= 360oder vertexIndex %= numberOfVertices(für die Scheitelpunktliste eines geschlossenen Polygons).
Sebastian Negraszus

Antworten:


12

Ein möglicher Grund ist , dass die logischen Operatoren &&und ||haben „Kurzschließen“ Verhalten. Der rechte Operand von &&und ||wird nur ausgewertet, wenn dies erforderlich ist. Vielleicht aus diesem Grund haben die Sprachdesigner entschieden, dass die Bedeutung eines Ausdrucks wie a ||= f()nicht offensichtlich ist, und deshalb sollten solche Operatoren besser weggelassen werden.


2
Ja. Zum Beispiel glauben viele Leute, dass a ||= bdies so interpretiert werden sollte a = a || b, aber tatsächlich kann es so sein a || a = b(wie in Ruby ). Sie können unterschiedlich sein, wenn der Setter Nebenwirkungen hat. Die Auswahl einer Option kann für Benutzer im anderen Camp schlecht sein. Ich persönlich mag den a || a = bWeg (den Ruby-Weg), bin mir aber nicht sicher, ob alle damit zufrieden sind.
Franklin Yu

8

Die allgemeine Antwort auf alle Fragen zu "Warum wurde diese Sprachfunktion nicht implementiert?" Ist, dass das Team, das die Sprache entworfen hat, entschieden hat, dass der Nutzen die Kosten nicht überwiegt.

Kosten können viele Formen annehmen. Die Implementierung eines Sprachfeatures erfordert viel Zeit und Mühe, ist jedoch auch mit den Kosten der Komplexität verbunden: Verursacht das Feature eine Komplexität oder Mehrdeutigkeit der Sprache, die in keinem Verhältnis zu ihrem potenziellen Nutzen steht?

Der hypothetische ||=Operator unterscheidet sich grundlegend von den anderen zusammengesetzten Zuweisungsoperatoren. Während die anderen Operatoren rein mathematischer Natur sind, ist dieser anders: Er ersetzt einen Wert durch einen anderen (in dem von Ihnen beschriebenen Kontext).

Angesichts dieser Mehrdeutigkeit (der Operator führt je nach Kontext zwei verschiedene Funktionen aus) ist es nicht schwer zu erkennen, warum er nicht in der Sprache enthalten war. Obwohl Sie sagen, dass sich das ändert

function (options) {
    options = options || {};
}

zu

function (options) {
    options ||= {};
}

Null-Koaleszenz durchzuführen ist ein wertvolles Merkmal, der Nutzen ist mir weit weniger klar. Wenn eine Wertersetzung erfolgen soll, erscheint es logisch (und klarer), beide Werte auf der rechten Seite des Gleichheitszeichens zu haben, um einen visuellen Hinweis darauf zu geben, dass eine solche Ersetzung auftreten kann.

C # hat einen anderen Pfad eingeschlagen und verwendet einen bestimmten Operator für die Nullzusammenführung.


1
Beim Lesen des Codes lautet das erste Beispiel natürlicher: "Optionen sind Optionen oder nichts" als das zweite: "Optionen sind Optionen oder nichts". Ich denke, dies ist nur ein weiterer Grund, warum der Operator "oder gleich" nicht berücksichtigt wurde
Andy Hunt

Ausgezeichnete Öffnung für Ihre Antwort. Und ich denke, der Anfang Ihrer Antwort gehört in das Wiki für den Tag.

3
@AndyBursh Dieselbe Logik könnte auf jeden zusammengesetzten Zuweisungsoperator angewendet werden. "X ist gleich X mal 2" ist natürlicher als "X ist gleich 2".
penartur

2
Beachten Sie, foo = foo || bardass Sie bei der Eingabe foozweimal eingeben müssen . Dies ist sowohl umständlich als auch anfällig für das Refactoring von Tippfehlern.
Phrogz

1
Ich denke, Sie verstehen die Bedeutung von "mathematisch" falsch, vielleicht haben Sie von Boolescher Algebra gehört. Ich bin damit einverstanden, dass das Erzwingen eines nicht-booleschen ||=Operators , um ihn als Null-Koaleszenzoperator zu verwenden, nicht intuitiv ist und tatsächlich in Codeform stumpf aussieht. Wo es nützlich wird, ist, wenn Sie versuchen, boolesche Mathematik zu tun. function fulfill(inValue) { if(resolved || rejected) return false; /* Do stuff here */ return true; } resolved ||= fulfill(value)
Joshperry

3

Sie haben Recht, das ||=ist ein nützliches Konstrukt. Es existiert in Perl.

Tatsächlich stellt Perl all diese zur Verfügung:

**=    +=    *=    &=    <<=    &&=   -=    /=    
|=     >>=   ||=   .=    %=     ^=    //=   x=

Einige davon sind großartig ( .=fügt etwas an das Ende eines Strings an), andere weniger ( &&=ich nehme an, die Variable würde auf die rechte Seite gesetzt, wenn sowohl sie als auch die Variable wahr sind. Aber warum sollten Sie das jemals tun? ?)

Was in einer Sprache enthalten ist, ist wirklich ein Merkmal ihrer Designphilosophie.


3
stackoverflow.com/questions/12589467/… wofür &&=bedeutet / tut.
Mat
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.