How do you read this JavaScript code? (var1 ? var2:var3) - javascript

I've seen this format used in JavaScript code, but can't find a good source for the meaning.
Edit for a follow-up:
Thanks for all the quick answers! I figured it was something like that. Now, for bonus points:
can you use
(var1 ? var2)
to do the same thing as
if (var1) {
var2
}
?

It's known as a ternary (because it has three operands) conditional (because it's an if/else/then) operator.
It is evaluated to a value, so you would usually use it to assign a value, such as:
var result = condition ? value1 : value2;
Which is equivalent to:
var result;
if (condition == true) {
result = value1;
} else {
result = value2;
}
An example:
var message = "Length is " + len + " " + (len==1 ? "foot" : "feet");
Note ?: is the full operator. It's not a ? and : operator, so ? by itself is meaningless in Javascript.

Its a conditional operator.
It is
if var1 then var2 else var3
Read more here
Conditional Operator
The conditional operator is the only
JavaScript operator that takes three
operands. This operator is frequently
used as a shortcut for the if
statement.

if(var1) {
var2;
else {
var3;
}

The expression var1 ? var2 : var3 returns the value of var2 if var1 is considered to have a value equivalent to true else it returns teh value of var3.
Note this is not quite the same as:-
if (var1)
varX = var2
else
varX = var3
Since the above construct can not itself appear as part of a larger expression.
In ternery expression, as ? : is known, one should avoid allowing the component expressions to have side effects other than perhaps the side-effects of ++ or -- operators. For example this isn't a good idea:-
varX = var1 ? doSomethingSignificant() : doSomethingElseSignificant();
In this case it would be better to use the if else construct. On the hand:-
varX = var1 ? calcSomething(var2) : someOtherCalc(var2);
this is acceptable assuming the called functions don't themselves modify the program state significantly.
Edit:
I think I need to re-enforce this point. Do not use the ternary operator as means to short cut on if statements. The two have different purposes. If your code is full of ? : that should be if else it will be difficult to read. We expect logical flow to appear in if statements. We expect ? : when there is a simple logical component to an expression. Note expressions do not modify things only the results of them when assigned should modify things.

As an addendum for the first question, you can alternatively use
var result = (condition) && var1 || var2;
and obtain the same result
For the second question, in C the following works too :
(condition) && someinstruction;
but that does not seem to work in javascript (at least with my version of firefox).

This seems to be sort of a ternary operation. Short form of an if else operation, so to say. check here for details...

Related

"value == var" versus "var == value"

At many places, I've seen developers doing value == var comparisons, like this:
if ('https' === location.protocol) {
port = 8443;
protocol = 'wss://';
isSecure = true;
}
I know that a == b is same as b == a, so why do people use value == var instead of var == value?
Is there a standard for this? And if yes, which is the standard way?
What you are seeing is yoda condition.
Yoda conditions describe the same expression, but reversed:
if ( 42 == $value ) { /* ... */ }
// Reads like: "If 42 equals the value..."
The advantage is
Placing the constant value in the expression does not change the behavior of the program (unless the values evaluate to falseā€”see below). In programming languages that use a single equals sign (=) for assignment and not for comparison, a possible mistake is to assign a value unintentionally instead of writing a conditional statement.
Note that it is clearly lack of readability. I personally don't prefer this way.

Javascript Ternary operator with empty else

I'm trying to convert the following if-else to it's ternary operator representation in javascript as follows
var x = 2;
if (x === 2) {alert("2");}
else
{ //do nothing}
But when I do this:
(t==2)?(alert("1")):();
Chrome throws a SyntaxError.
My question is -
How to have a ternary operator in javascript with an empty "else" branch - i.e the part that comes after ":".
Also, is this allowed- using a ternary operator in javascript to execute statements - NOT do assignment.
Also: the above code was just a base case. I'm actually trying to get all the DOM elements of the page as an array (called all2) and then add only those elements to another array (called only) only if they have non-null class names. Here is my code:
all2.forEach(function(e){ e.getAttribute("class") ? (only.push(e.getAttribute("class"))) : (); });
If I leave the third operand blank, it throws a syntax error. Passing a null works
Answer to your real question in the comments:
all2.forEach(function (e) {
e.getAttribute("class") && only.push(e.getAttribute("class"));
});
Do this :
(t==2)?(alert("1")):null;
You could replace null by any expression that has no side effect. () is not a valid expression.
You putted a lot of useless parentheses, and the best NULL value in js is undefined.
document.getElementById('btn-ok').onclick = function(){
var val = document.getElementById('txt-val').value;
val == 2 ? alert(val) : undefined;
}
<input id="txt-val" type="number" />
<button type="button" id="btn-ok">Ok</button>
using a single line if statement is better though
if(value === 2) alert(value);
you have a few options to do this nicely in one line:
option1 - noop function
set a global noop function:
function noop(){}
(t==2)?(alert("1")):(noop());
option2 - && operator
when you use && operater, operands are evaluted only if previos ones where true, so you could miply write:
(t==2) && alert("1");
or, for exapmle if you have an arry you want to push to, you could test it is not null before:
arr && arr.push(obj)
I don't like it's either. So you're on the right track looking for alternatives.
In this case, I would write:
t===2 && alert("2")
Your idea is valid too, for instance you can do this:
t===2 ? alert("2") : null
But it's four extra chars.
In that case you don't need to use Ternary operator. Ternary operator requires a third argument.
condition ? expr1 : expr2
Lokki at Conditional (ternary) Operator
You can use the if statement
if ( t == 2 ) alert(1);
NO, you can't have empty else, better don't use the ternary operator, it requires a third argument. Go with simple if condition.
if(t==2) alert("2");

Simple substitute of assignment operators of logical ones in JavaScript?

JavaScript has assignment operators corresponding to arithmetic ones: +=, -=, *=, /=, %=.
JavaScript also has assignment operators corresponding to bitwise ones: <<=, >>=, >>>=, &=, ^=, |=.
But it doesn't have assignment operators corresponding to logical ones: ||=, &&=.
Then, I can't do things like
aVeryLongVariableIdontWantToRepeat ||= 1;
In this other question it's explained why JS Java doesn't have such operators. I guess it's the same for JS.
But I want to know if there is a simple way to emulate them, avoiding
aVeryLongVariableIdontWantToRepeat = aVeryLongVariableIdontWantToRepeat || 1;
No, there isn't. I feel like there should be more to this answer, but really, that's it. The shortest version of a = a || x is ... a = a || x.
It might help you to investigate writing your code using Coffeescript, which has the ||= operator available.
There isn't a shorter way: a = a || 1 is the simplest way to do it.
However, to avoid unnecessary assignment of values (slightly at the expense of readability) you can also do a || ( a = 1).
JSFIDDLE
var a,b='x';
a || ( a = 1 );
b || ( b = 2 );
console.log( a + ', ' + b ); // Outputs "1, x"

Best Way for Conditional Variable Assignment

Which is the better way for conditional variable assignment?
1st method
if (true) {
var myVariable = 'True';
} else {
var myVariable = 'False';
}
2nd Method
var myVariable = 'False';
if (true) {
myVariable = 'True';
}
I actually prefer 2nd one without any specific technical reason. What do you guys think?
try this
var myVariable = (true condition) ? "true" : "false"
There are two methods I know of that you can declare a variable's value by conditions.
Method 1: If the condition evaluates to true, the value on the left side of the column would be assigned to the variable. If the condition evaluates to false the condition on the right will be assigned to the variable. You can also nest many conditions into one statement.
var a = (true)? "true" : "false";
Nesting example of method 1: Change variable A value to 0, 1, 2 and a negative value to see how the statement would produce the result.
var a = 1;
var b = a > 0? (a === 1? "A is 1" : "A is not 1") : (a === 0? "A is zero" : "A is negative");
Method 2: In this method, if the value of the left of the || is equal to zero, false, null, undefined, or an empty string, then the value on the right will be assigned to the variable. If the value on the left of the || does not equal to zero, false, null undefined, or an empty string, then the value on the left will be assigned to the variable.
Although the value on the left can be an undefined value for JS to evaluate the condition but the variable has to be declared otherwise an exception will be produced.
var a = 0;
var b = a || "Another value";
An alternative way of doing this is by leveraging the ability of logical operators to return a value.
let isAnimal = false;
let isPlant = true;
let thing = isAnimal && 'animal' || isPlant && 'plant' || 'something else';
console.log(thing);
In the code above when one of the flags is true isAnimal or isPlant, the string next to it is returned. This is because both && and || result in the value of one of their operands:
A && B returns the value A if A can be coerced into false; otherwise, it returns B.
A || B returns the value A if A can be coerced into true; otherwise, it returns B.
Answer inspired by this article: https://mariusschulz.com/blog/the-and-and-or-operators-in-javascript
PS: Should be used for learning purposes only. Don't make life harder for you and your coworkers by using this method in your production code.
You could do a ternary, which is a lot shorter (and no darn curly braces):
var myVariable = (true) ? 'True' : 'False';
Another cool thing is that you can do multiple assignment based on a conditional:
let [long_str, short_str] = a.length > b.length ? [a, b] : [b, a]
Third way when you are storing only true false in variabel then use
var myVariable =(condition_written_in_if);
Just for completion, there is another way in addition to all the others mentioned here, which is to use a lookup table.
Say you have many possible values, you could declaratively configure a Map instead of using an if, switch or ternary statement.
Object map = {
key1: 'value1',
key2: 'value2,
keyX: 'valueX'
};
var myVariable = map[myInput];
This works even for booleans:
Object map = { true: 'value1', false: 'value2 };
var myVariable = map[myBoolean];
For booleans you would probably do it the 'normal' way though with logic operators specifically designed for that. Though sometimes it can be useful, such as:
portability: you can pass a map around
configurability: maybe the values come from a property file
readability: if you don't care it's a boolean or not, you just want to avoid conditional logic and reduce cognitive load that way
Note there is some overlap between the advantages using a lookup map and advantages of using a function variable (closure).
The first solution uses only one assignment instead of 1,5 by average in the second code snippet. On the other hand the first code snippet is less readable as people not familiar with JavaScript might not realize that the scope of a variable is not block oriented by function oriented - on other languages with C-like syntax myVariable would not be accessible outside if and else blocks.
In other words both solutions have disadvantages. What about ternary operator:
var myVariable = condition? 'True' : 'False';
or if you don't care about the camel-case (although I understand this is just an example, not a real code);
var myVariable = (!!condition).toString();
If you tired of ternary operator then use IIFE
Another way would be to use Immediately Invoked Function Expression. The good thing about it is that it can hold some logic and can be encapsulated from the outside world.
const direction = "n";
const directionFull= (() => {
switch(direction ){
case "n": return "north";
case "s": return "south";
case "w": return "west";
case "e": return "east";
}
})()
console.log(directionFull);
I would prefer 2nd option too, no technical reason but for the sake of easy to read code, readability is very important in code.
If you see the second option, from processing point of view only one check will ever be executed, saved some very minute processing time, so there is only one check in second case.
It depends on the use for me. If I have code that I only want to run if true, but with no extra code for false, I'll use the second. If I want to execute some code on true, and different on false, I use the first. It all depends on use, but the general rule for me is to write once. Keep it clean, keep it simple, and keep it short
Maybe you simply need && operator to check if boolean is true, if it is, assing "myVariable" to true.
var myVariable = 'False';
true && myVariable = 'True';
If all you need to do is convert a boolean to a string, you should do so explicitly:
var myBool = true;
var myVariable = myBool.toString(); // 'true'
// '' + myBool, ''.concat(myBool), etc. also work
If it's important that the first letter be capitalized, as in your example, that is not difficult to do; see e.g. this answer.
Another approach with Map and Object: (Maps are more flexible with key types and Objects are more readable IMHO)
const condition_var = 'e'
const options1 = new Map([ ['n','north'],['s','south'],['e','east'],['w','west']])
const myVar1 = options1.get(condition_var) || null
const options2 = {n:'north', s:'south', e:'east', w:'west'}
const myVar2 = options2[condition_var] || null
console.log(myVar1)
console.log(myVar2)

food for thought: return in if statement

I can put a return anywhere such as in a function, in an if block, case block.
How come this doesn't work:
(x == "good") ? (return("works")):"";
UPDATE: I know I can do this:
return (x == "good") ? ("works"):"";
Just want to know why the first case isn't acceptable.
It's because the grammar of a ternary operation is this:
condition ? expr1 : expr2
And a return statement isn't technically considered an expression.
Edit: here's some more info. The above explains it in terms of the grammar of the language, but here's a little bit about the reasoning of why.
I've actually dug into this before, because I've always thought it would be cool to be able to do stuff like:
someFlag && return;
Rather than
if (someFlag) return;
The problem, however, is that expressions always need to evaluate to something. This requirement is at odds with the role of the return statement, however, which along with (optionally) returning a result, also immediately terminates execution of the current function. This termination of the current function is logically inconsistent with the need to evaluate the value of the return statement itself, if it were indeed an expression.
Given that inconsistency, the language authors apparently chose to not allow return statements to act as expressions. Hope I managed to word that in a way that makes sense.
are you trying to do this:
return (x == "good") ? "works":"";
return isn't a function, so return("works") isn't correct.
alternatively you could also do:
var x = "bad";
var y = (x=="good")? "works" : "";
return y;
but this is more verbose. So to answer your question, you can put return anywhere in a function, but anything after it won't be executed. so
function x ()
{
var str = "";
return "I love puppies.";
str = "me too!" //this won't ever execute, because return exits the function.
}
The one exception to this is variable declaration, because variables are automatically declared at the beginning no matter where you put them.
function y (){
return "";
var x;
}
is really:
function y (){
var x;
return "";
}
The return keyword should come first:
return (x == "good") ? "works": "";
The reason is that return x; is a statement. You can't use (return x) as an expression.
All expressions can be used where a statement is expected, but not all statements can be used where an expression is expected.
The return keyword marks the beginning of a statement. It is not an expression, which you could use with the ternary operator.
Based off of this grammar for javascript, The ternary operator is defined as :
OrExpression ? AssignmentExpression : AssignmentExpression
Whereas return is a statement (well, the beginning of one anyways).
In any case messing with control flow in an "expressive" (read: "I want to be clever") form like ternary expressions would not be recommended by anyone I know. an if statement is the same amount of characters:
if(x==good) return x;
(x==good)?(return x)
Because "Almost everything is an expression" hasn't made it into the language yet.
Are you saying if x is "good", then return, otherwise do nothing else? In that case,
if (x == "good") return "works";
does the trick. Furthermore, return is not a function, it is a javascript token, so no parentheses should be used with return.
All the answers that begin with "return" are doing different behavior from what I think the OP intended in his ternary operation. I'm guessing the OP wants
x == "good" ? return "works" : "";
to mean
if(x == "good") {
return works;
}
else {
""; //does nothing because the statement ""; has no side effects
}
It doesn't do this because the format is
statement1 ? statement2 : statement3;
All statements may have side-effects but only the return value (in the case of statement1, just the truthiness of it) are considered by the ternary operator.
Even though the ? : is best read in terms of "if" and "then," when thinking closer to the level of syntax it should be thought of as an expression that factors into side-effects and a return value. If you understand the difference between x++ and ++x, you will be able to understand the ternary operator.
By way of example, here are some illegal statements that are illegal for the same reason.
if( (return 5) == 5) {
//...
}
if (loadUserStats(return userId)) == "FAILED") {
throw error("oops");
}
x = return y++;

Categories

Resources