Ternäre Operatoren in JavaScript ohne "sonst"


149

Ich musste immer nulldie anderen Bedingungen festlegen, die nichts haben. Gibt es sowieso um ihn herum? Z.B

condition ? x = true : null;

Grundsätzlich gibt es eine Möglichkeit:

condition ? x = true;

Jetzt wird es als Syntaxfehler angezeigt

Zu Ihrer Information, hier ist ein echter Beispielcode:

!defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null;

21
Die Verwendung eines ternären Like condition ? x = true : null;sollte wahrscheinlich als geschrieben werden x = (condition ? true : null);. Abgesehen davon wird Javascript nullals falsch ausgewertet, sodass Sie in DIESEM Fall x = (condition);das gleiche Ergebnis erzielen können.
Matt S

1
matt, deine Antwort ist am besten, aber es ist keine Antwort, es ist ein Kommentar!
Cheeso

Matt, mein IST-Code lautet :! Defaults.slideshowWidth? defaults.slideshowWidth = obj.find ('img'). width () + 'px': null; eine kürzere, bessere Art, das zu schreiben?
Oscar Godson

2
defaults.slideshowWidth = defaults.slideshowWidth || obj.find ('img'). width () + 'px';
kennebec

Es wäre besser, die Identitätszuweisung zu vermeiden, daher sollte dies nur eine Bedingung sein:if (!defaults.slideshowWidth) defaults.slideshowWidth = obj.find('img').width()+'px'
Mihail Malostanidis

Antworten:


225

Erstens ist ein ternärer Ausdruck kein Ersatz für ein if / else-Konstrukt - er entspricht einem if / else-Konstrukt, das einen Wert zurückgibt . Das heißt, eine if / else-Klausel ist Code, ein ternärer Ausdruck ist ein Ausdruck , was bedeutet, dass er einen Wert zurückgibt.

Dies bedeutet mehrere Dinge:

  • Verwenden Sie ternäre Ausdrücke nur, wenn Sie auf der linken Seite eine Variable haben =, der der Rückgabewert zugewiesen werden soll
  • Verwenden Sie ternäre Ausdrücke nur, wenn der zurückgegebene Wert einer von zwei Werten sein soll (oder verwenden Sie verschachtelte Ausdrücke, wenn dies passt).
  • Jeder Teil des Ausdrucks (nach? und nach :) sollte einen Wert ohne Nebenwirkungen zurückgeben (den Ausdruck x = true gibt true zurück, da alle Ausdrücke den letzten Wert zurückgeben, ändert aber auch x, ohne dass x Auswirkungen auf den zurückgegebenen Wert hat).

Kurz gesagt - die "richtige" Verwendung eines ternären Ausdrucks ist

var resultofexpression = conditionasboolean ? truepart: falsepart;

Anstelle Ihres Beispiels condition ? x=true : null ;, in dem Sie einen ternären Ausdruck verwenden, um den Wert von festzulegenx festzulegen, können Sie Folgendes verwenden:

 condition && (x = true);

Dies ist immer noch ein Ausdruck und könnte daher die Validierung nicht bestehen, daher wäre ein noch besserer Ansatz

 void(condition && x = true);

Der letzte besteht die Validierung.

Wenn der erwartete Wert ein Boolescher Wert ist, verwenden Sie einfach das Ergebnis des Bedingungsausdrucks

var x = (condition); // var x = (foo == "bar");

UPDATE In Bezug auf Ihre Stichprobe ist dies wahrscheinlich angemessener:

defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';

4
Brillantes SO, das Bearbeiten kann i/elseTippfehler nicht korrigieren, da nicht genügend Zeichen vorhanden sind.
Tau

1
void (Bedingung && x = true) - das sieht gut aus, scheint aber den Fehler "ungültige Zuordnung auf der linken Seite"
auszulösen

1
void (Bedingung && (x = true)) // hält die Zuordnung vom ersten Wert getrennt
diamondsea

4
Dies ist jedoch nicht intuitiv zu lesen, insbesondere für Entwickler, die nicht an diesen Stil gewöhnt sind. Sie könnten dies genauso einfach und leserlicher schreiben als: if (Bedingung) {x = true; }
Diamondsea

2
Können Sie erklären, was Sie unter "Validierung möglicherweise nicht bestanden" verstehen? Ich verstehe nicht, warum man den Ausdruck einwickeln sollte void(). Vielen Dank.
Gilad Mayani

20

Nein, es werden drei Operanden benötigt. Deshalb werden sie ternär genannt Operatoren genannt.

Für das, was Sie als Beispiel haben, können Sie jedoch Folgendes tun:

if(condition) x = true;

Obwohl es sicherer ist, geschweifte Klammern zu haben, wenn Sie in Zukunft mehr als eine Anweisung hinzufügen müssen:

if(condition) { x = true; }

Bearbeiten: Nun, da Sie den tatsächlichen Code erwähnen, in dem Ihre Frage gilt:

if(!defaults.slideshowWidth)
    { defaults.slideshowWidth = obj.find('img').width()+'px'; }

1
Sie können, aber Sie sollten nicht. Zumindest nicht ohne geschweifte Klammern - es ist sehr fehleranfällig.
Konerak

1
ist das wahr? Ich habe verstanden, dass der Hauptgrund für das Erfordernis von Locken darin besteht, dass sie das Leben von jslint erleichtern.
Cheeso

@Cheeso ist fehleranfällig im Sinne von Refactoring. Sie kommen zurück, um im Falle eines echten Zustands mehr zu tun, ohne zu bemerken, dass es dort keine geschweiften Klammern gibt. Der neue Code wird immer ausgeführt und nicht, wenn er wahr ist.
Matt S

Nein, ich weiß, ich schreibe einfach gerne Bedingungen ohne Extras wie if () {} else {}, wenn es einfach ist?:;
Oscar Godson

3
Ehrlich gesagt, ich habe noch nie Entwickler gekannt, die mehr Angst vor der Verwendung einer Sprache haben als Javascript: -PIch möchte nicht, dass mir jemand sagt, dass ich keine geschweiften Klammern verwenden soll. Ich lasse sie oft weg und habe nie mehr Probleme, als ich versehentlich eine Zahnspange vermissen würde.
Andy E

12

Häufiger werden logische Operatoren verwendet, um die Anweisungssyntax zu verkürzen:

!defaults.slideshowWidth &&
  (defaults.slideshowWidth = obj.find('img').width()+'px');

In Ihrem speziellen Fall kann die Syntax jedoch noch einfacher sein

defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';

Dieser Code gibt den defaults.slideshowWidthWert zurück, wenn der Wert defaults.slideshowWidthauf true und der obj.find('img').width()+'px'Wert andernfalls ausgewertet wird .

Weitere Informationen finden Sie in der Kurzschlussbewertung logischer Operatoren.


11
var x = condition || null;

2
(defaults.slideshowWidth) || (defaults.slideshowWidth = obj.find('img').width()+'px')oderdefaults.slideshowWidth = defaults.slideshowWidth || (obj.find('img').width()+'px')
Casey Chu

> Gibt expr1 zurück, wenn es in true konvertiert werden kann. Andernfalls wird expr2 zurückgegeben. Logische Operatoren (MDN)
Szabolcs Páll

5

Du könntest schreiben

x = condition ? true : x;

Damit ist x unverändert, wenn die Bedingung falsch ist.

Dies entspricht dann

if (condition) x = true

BEARBEITEN:

!defaults.slideshowWidth 
      ? defaults.slideshowWidth = obj.find('img').width()+'px' 
      : null 

Es gibt ein paar Alternativen - ich sage nicht, dass diese besser / schlechter sind - nur Alternativen

Die Übergabe von null als dritter Parameter funktioniert, da der vorhandene Wert null ist. Wenn Sie den Zustand umgestalten und ändern, besteht die Gefahr, dass dies nicht mehr der Fall ist. Übergabe des bestehenden Wertes als 2. Wahl in den ternären Wachen dagegen:

!defaults.slideshowWidth = 
      ? defaults.slideshowWidth = obj.find('img').width()+'px' 
      : defaults.slideshowwidth 

Sicherer, aber vielleicht nicht so schön anzusehen und mehr zu tippen. In der Praxis würde ich wahrscheinlich schreiben

defaults.slideshowWidth = defaults.slideshowWidth 
               || obj.find('img').width()+'px'

Einige Live-Code ist (sowieso, um die Null in diesem zu entfernen?) :! Defaults.slideshowWidth? defaults.slideshowWidth = obj.find ('img'). width () + 'px': null;
Oscar Godson

2

In Ihrem Fall sehe ich den ternären Operator als redundant an. Sie können die Variable mit den Operatoren ||, && direkt dem Ausdruck zuweisen.

!defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null ;

wird werden :

defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';

Es ist klarer, es ist mehr "Javascript" -Stil.


2

Was ist mit einfach

    if (condition) { code if condition = true };

1

Um einen ternären Operator ohne weiteres innerhalb eines Arrays oder einer Objektdeklaration zu verwenden, können Sie den ES6-Spread-Operator verwenden ...()

const cond = false;
const arr = [
  ...(cond ? ['a'] : []),
  'b',
];
    // ['b']

Und für Objekte:

const cond = false;
const obj = {
  ...(cond ? {a: 1} : {}),
  b: 2,
};
    // {b: 2}

Originalquelle

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.