Ternary operators in JavaScript without an "else"
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'
Related videos on Youtube
Oscar Godson
Fork me on Github: http://github.com/oscargodson Read my stuff: http://oscargodson.com
Updated on April 10, 2022Comments
-
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 almost 14 yearsuse of a ternary like
condition ? x = true : null;
should probably be written asx = (condition ? true : null);
. As an aside, in javascriptnull
evaluates to false so in THIS case you couldx = (condition);
and achieve the same result. -
Cheeso almost 14 yearsmatt, your answer is best, but it's not an answer, it's a comment!
-
Oscar Godson almost 14 yearsMatt, my ACTUAL code is: !defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null ; a shorter, better way to write that?
-
kennebec almost 14 yearsdefaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px' ;
-
Mihail Malostanidis over 5 yearsit 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 over 5 yearsBut the name
defaults
strongly suggests that you shouldn't be mutating it here, so I suggestconst actualWidth = defaults.slideshowWidth || obj.find('img').width()+'px'
. Also, be careful ifslideshowWidth
might be an explicit 0, as that's falsy. -
Nina Scholz about 5 yearsplease add the value of
x
before the condition check takes place. -
Gibin Ealias over 4 years@Cheeso
x = (condition ? true : null);
will assignnull
value to thex
if the condition is not satisfied. That's not expected generally.
-
-
Konerak almost 14 yearsYou can, but you shouldn't. Atleast not without curly brackets around it - it's very errorprone.
-
Cheeso almost 14 yearsis that true? I understood the main reason for requiring curlies is because they make jslint's life easier.
-
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 almost 14 yearsNo i know, i just like writing conditionals without extras such as if(){}else{} when its equal to simply ?:;
-
Oscar Godson almost 14 yearsSome live code is (anyways to get rid of the null in this?): !defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null ;
-
Oscar Godson almost 14 yearslike 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 almost 14 yearsHonestly, 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 almost 14 years@mdma How is it sidestepped? I made it clear that you can't have a two-operand ternary operator.
-
Casey Chu almost 14 years
(defaults.slideshowWidth) || (defaults.slideshowWidth = obj.find('img').width()+'px')
ordefaults.slideshowWidth = defaults.slideshowWidth || (obj.find('img').width()+'px')
-
Oscar Godson almost 14 yearsI 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 about 9 yearsbrilliant SO, not allowing edit to correct
i/else
typo as it's not enough characters. -
Eugene Tiurin over 8 yearsvoid(condition && x = true) - this looks great but seem to throw "invalid assignment left-hand side" error
-
Szabolcs Páll over 8 years> Returns expr1 if it can be converted to true; otherwise, returns expr2. Logical Operators (MDN)
-
diamondsea about 8 yearsvoid(condition && (x = true) ) // keeps the assignment separate from the first value
-
diamondsea about 8 yearsHowever, 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 over 6 yearsCould 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 about 6 yearsCould you explain what do you mean by "might not pass validation"? I don't understand why one should wrap the expression in
void()
. thanks.