Javascript Ternary Operator gegen ||

17

Ich habe mir vorhin einen Code in node.js angesehen und festgestellt, dass der Typ, der ihn geschrieben hat, die folgende Syntax zu bevorzugen scheint:

var fn = function (param) {
    var paramWithDefault = null == param ? 'Default Value' : param;
}

Über das, was ich für das prägnantere halte:

var fn = function (param) {
    var paramWithDefault = param || 'Default Value';
}

Ich habe mich gefragt, ob die zweite Form tatsächlich eine sozialverträglichere JavaScript-Syntax ist. Ich habe sie in der Natur öfter gesehen als der ternäre Operator für diesen Zweck.

Ich stelle fest, dass er im ersten Beispiel das Doppelte Gleiche (nicht das Dreifache Gleiche) verwendet, was bedeutet, dass "undefiniert" als null gezählt wird, was eine Auswirkung verringert, die ich mir vorstellen könnte. Ich habe jedoch an zahlreichen Stellen gelesen, dass == ein ziemlich schlechter Operator in JavaScript ist (JSLint ist sehr dagegen, IIRC).

Ed James
quelle
2
Kommentatoren : Kommentare dienen der Klarstellung und nicht der ausführlichen Diskussion. Wenn Sie eine Lösung haben, hinterlassen Sie eine Antwort. Wenn Ihre Lösung bereits veröffentlicht wurde, stimmen Sie sie bitte ab. Wenn Sie diese Frage mit anderen diskutieren möchten, verwenden Sie bitte den Chat . Weitere Informationen finden Sie in den FAQ .

Antworten:

17

Da dieser Code bei jeder Übergabe von 0, "", false oder einem anderen falschen Wert als "Standardwert" ausgewertet wird.

function fn(param) {
  var paramWithDefault = param || 'Default Value';
  return paramWithDefault;
}

Es wird Sie vielleicht nicht bei der Verwendung dieser bestimmten Funktion stören, aber es ist ein schlechtes Muster, das Sie vermeiden sollten, wenn Sie Dinge wie leere Zeichenfolgen oder 0 oder einen Booleschen Wert übergeben möchten.

Peter Smith
quelle
Sie sollten für ein Objekt nur eine Null-Vereinigung verwenden. Wenn ein Objekt definiert ist, funktioniert dies nicht. Mit vielleicht der Ausnahme der leeren Zeichenfolge.
Malfist
4
Der Null-Vergleich ist ein guter Punkt, der ziemlich unerwartet sein könnte.
Ed James
1
+1 - Dieses Problem ist genau der Grund, warum Python (irgendwann) die Syntax "x if y else z" hinzugefügt hat. Diese Semantik für logische Operatoren ist ziemlich häufig, und dieselben häufigen Fehler treten immer dann auf, wenn sich Redewendungen auf sie stützen, um die Arbeit von Operatoren für bedingte Auswahl zu erledigen.
Steve314
Vergessen Sie jedoch nicht, Ihre Konstrukte in Klammern zu setzen. Wenn Sie sie zusammen mit der Verkettung von Zeichenfolgen verwenden var txt = 'Hello, ' + (user_name||'User') + '!';, funktioniert dies, aber ohne Klammern erhalten Sie undefined. jsfiddle.net/4mFAB/1
c69
7

Was Sie wirklich brauchen, ist ein Null-Koaleszenz-Operator. Aber da Javascript nicht wirklich eines hat, verwenden Programmierer normalerweise '||' dafür einzustehen.

Beides ist jedoch durchaus sinnvoll. Für diejenigen, die nicht verstehen, was ein Null-Koaleszenz-Operator ist, ist es wahrscheinlich wahrscheinlicher, dass der ternäre Operator verstanden wird.

Malfist
quelle
Ein weiterer verwandter Operator ist der Icon-Operator IIRC "else". Dadurch wird ein spezielles "Fehler" -Ergebnis aus dem ersten Argument erkannt und das zweite Argument in diesem Fall als Alternative verwendet. Ich wünschte, Pythons "x wenn y sonst z" würden mit zwei separaten Operatoren implementiert - einem binären Assertionsoperator "wenn" und einem symbolartigen "sonst" -Operator - wobei diese beiden Operatoren unabhängig voneinander verwendet werden könnten. Icon hat diesen Stil jedoch nicht unterstützt, sondern mit relativen Operatoren etwas Seltsames gemacht.
Steve314
@ Steve314: Python hat etwas, das Sie sich gewünscht haben: einen separaten else-Operator [false-part, true-part]mit einem separaten if-Operator, der in [..][bool(condition)]kombiniert wird [false-part, true-part][bool(condition)]. Wenn du faul sein willst, kannst du einfach den wahren und den falschen Teil lambda.
Lie Ryan