Ternary operators in JavaScript without an "else"

205,848

Solution 1

First of all, a ternary expression is not a replacement for an if/else construct - it's an equivalent to an if/else construct that returns a value. That is, an if/else clause is code, a ternary expression is an expression, meaning that it returns a value.

This means several things:

  • use ternary expressions only when you have a variable on the left side of the = that is to be assigned the return value
  • only use ternary expressions when the returned value is to be one of two values (or use nested expressions if that is fitting)
  • each part of the expression (after ? and after : ) should return a value without side effects (the expression x = true returns true as all expressions return the last value, but it also changes x without x having any effect on the returned value)

In short - the 'correct' use of a ternary expression is

var resultofexpression = conditionasboolean ? truepart: falsepart;

Instead of your example condition ? x=true : null ;, where you use a ternary expression to set the value of x, you can use this:

 condition && (x = true);

This is still an expression and might therefore not pass validation, so an even better approach would be

 void(condition && x = true);

The last one will pass validation.

But then again, if the expected value is a boolean, just use the result of the condition expression itself

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

UPDATE

In relation to your sample, this is probably more appropriate:

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

Solution 2

No, it needs three operands. That's why they're called ternary operators.

However, for what you have as your example, you can do this:

if(condition) x = true;

Although it's safer to have braces if you need to add more than one statement in the future:

if(condition) { x = true; }

Edit: Now that you mention the actual code in which your question applies to:

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

Solution 3

More often, people use logical operators to shorten the statement syntax:

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

But in your particular case the syntax can be even simpler:

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

This code will return the defaults.slideshowWidth value if the defaults.slideshowWidth is evaluated to true and obj.find('img').width() + 'px' value otherwise.

See Short-Circuit Evaluation of logical operators for details.

Solution 4

var x = condition || null;

Solution 5

You could write

x = condition ? true : x;

So that x is unmodified when the condition is false.

This then is equivalent to

if (condition) x = true

EDIT:

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

There are a couple of alternatives - I'm not saying these are better/worse - merely alternatives

Passing in null as the third parameter works because the existing value is null. If you refactor and change the condition, then there is a danger that this is no longer true. Passing in the exising value as the 2nd choice in the ternary guards against this:

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

Safer, but perhaps not as nice to look at, and more typing. In practice, I'd probably write

defaults.slideshowWidth = defaults.slideshowWidth 
               || obj.find('img').width()+'px'
Share:
205,848

Related videos on Youtube

Oscar Godson
Author by

Oscar Godson

Fork me on Github: http://github.com/oscargodson Read my stuff: http://oscargodson.com

Updated on April 10, 2022

Comments

  • Oscar Godson
    Oscar Godson about 2 years

    I've always had to put null in the else conditions that don't have anything. Is there a way around it?

    For example,

    condition ? x = true : null;
    

    Basically, is there a way to do the following?

    condition ? x = true;
    

    Now it shows up as a syntax error.

    FYI, here is some real example code:

    !defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null;
    
    • Matt S
      Matt S almost 14 years
      use of a ternary like condition ? x = true : null; should probably be written as x = (condition ? true : null);. As an aside, in javascript null evaluates to false so in THIS case you could x = (condition); and achieve the same result.
    • Cheeso
      Cheeso almost 14 years
      matt, your answer is best, but it's not an answer, it's a comment!
    • Oscar Godson
      Oscar Godson almost 14 years
      Matt, my ACTUAL code is: !defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null ; a shorter, better way to write that?
    • kennebec
      kennebec almost 14 years
      defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px' ;
    • Mihail Malostanidis
      Mihail Malostanidis over 5 years
      it would be better to avoid the identity assignment, so this should just be a condition: if (!defaults.slideshowWidth) defaults.slideshowWidth = obj.find('img').width()+'px'
    • Mihail Malostanidis
      Mihail Malostanidis over 5 years
      But the name defaults strongly suggests that you shouldn't be mutating it here, so I suggest const actualWidth = defaults.slideshowWidth || obj.find('img').width()+'px'. Also, be careful if slideshowWidth might be an explicit 0, as that's falsy.
    • Nina Scholz
      Nina Scholz about 5 years
      please add the value of x before the condition check takes place.
    • Gibin Ealias
      Gibin Ealias over 4 years
      @Cheeso x = (condition ? true : null); will assign null value to the x if the condition is not satisfied. That's not expected generally.
  • Konerak
    Konerak almost 14 years
    You can, but you shouldn't. Atleast not without curly brackets around it - it's very errorprone.
  • Cheeso
    Cheeso almost 14 years
    is that true? I understood the main reason for requiring curlies is because they make jslint's life easier.
  • Matt S
    Matt S almost 14 years
    @Cheeso it's errorprone in the sense of refactoring. YOu come back to add more to do in the case of a true condition without realizing there's no curly braces there. The new code will always execute rather than the case of when true.
  • Oscar Godson
    Oscar Godson almost 14 years
    No i know, i just like writing conditionals without extras such as if(){}else{} when its equal to simply ?:;
  • Oscar Godson
    Oscar Godson almost 14 years
    Some live code is (anyways to get rid of the null in this?): !defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null ;
  • Oscar Godson
    Oscar Godson almost 14 years
    like i said, i know how to do a normal If/else conditional :) im asking if it was possible with a ternary, but it looks like not, thanks!
  • Andy E
    Andy E almost 14 years
    Honestly, I've never known developers more scared of using a language than Javascript :-P I wouldn't like someone telling me that I shouldn't use curly braces. I omit them a lot and never have any more trouble than I would accidentally missing a brace.
  • In silico
    In silico almost 14 years
    @mdma How is it sidestepped? I made it clear that you can't have a two-operand ternary operator.
  • Casey Chu
    Casey Chu almost 14 years
    (defaults.slideshowWidth) || (defaults.slideshowWidth = obj.find('img').width()+'px') or defaults.slideshowWidth = defaults.slideshowWidth || (obj.find('img').width()+'px')
  • Oscar Godson
    Oscar Godson almost 14 years
    I think he means you didn't give an option other than if/else, which is fine, but I think mdma was looking more for (which some others gave): defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px' ;
  • dewd
    dewd about 9 years
    brilliant SO, not allowing edit to correct i/else typo as it's not enough characters.
  • Eugene Tiurin
    Eugene Tiurin over 8 years
    void(condition && x = true) - this looks great but seem to throw "invalid assignment left-hand side" error
  • Szabolcs Páll
    Szabolcs Páll over 8 years
    > Returns expr1 if it can be converted to true; otherwise, returns expr2. Logical Operators (MDN)
  • diamondsea
    diamondsea about 8 years
    void(condition && (x = true) ) // keeps the assignment separate from the first value
  • diamondsea
    diamondsea about 8 years
    However, this is not intuitive to read, especially for developers not used to this style. You could just as easily and more readably write this as: if (condition) { x=true; }
  • Koenigsberg
    Koenigsberg over 6 years
    Could you elaborate on why precisely a conditional ternary operator should only be used when its resulting value is assigned to your variable? I refer to point one of your list. The intention is understandable, but I would like to know if there is a specific reason not to use the ternary operator when the returned value is unused, such as performance, safety or something else.
  • gilad905
    gilad905 about 6 years
    Could you explain what do you mean by "might not pass validation"? I don't understand why one should wrap the expression in void(). thanks.