Proper use of a comma in javascript ternary operator - javascript

Rather than use an if else statement, I'm trying to use the ternary operator but have a syntax error somewhere in my statement.
Can someone tell me where I am going wrong?
Statement is:
my_alert(status ? ('Accepted', 'alert-success') : ('Declined', 'alert-info'))
my_alert is a function which has 2 parameters.
Status just evaluates to true or false.
When I pass more than 1 parameter into the above expression, it doesn't like the use of the comma.
In chrome and firefox when the function runs it displays 'alert-success' or 'alert-info'. It misses out the first parameter.
I've looked on stackoverflow for the answer but by all means it's telling me that what i'm doing is correct.
Any help would be great.

Well, the comma operator does the following:
The comma operator evaluates both of its operands (from left to right) and returns the value of the second operand.
That means, ('Accepted', 'alert-success') evaluates to 'alert-success' (as you already noticed). The comma here is different than the comma that separates function arguments. You cannot use it to pass two arguments to a function.
What you can do is store both arguments in an array and use .apply to pass them to the function:
// this is not the comma operator either, this is array literal syntax.
var args = status ? ['Accepted', 'alert-success'] : ['Declined', 'alert-info'];
my_alert.apply(null, args);

I don't think ternary operators can be used to control two values like that:
How about separating them:
my_alert(($status?"Accepted":"Declined"),($status?"alert-success":"alert-info"));

Alternatively, you could just wrap the function call in the ternary statement...
status ? my_alert("Accepted", "alert-success") : my_alert("Declined", "alert-info");
UPDATE:
Robin van Baalen makes a good suggestion...
my_alert.apply(this, status ? ["Accepted", "alert-success"] : ["Declined", "alert-info"]);

You can't use the comma like that. If you want to pass 2 parameters, you need to use 2 ternary statements.
my_alert((status ? 'Accepted' : 'Declined'), (status ? 'alert-success' : 'alert-info'));
In your case, the comma is read a the comma operator, which evaluates both operands and returns the last one. So, your ternary statement was equivalent to:
my_alert(status ? 'alert-success' : 'alert-info')

Related

nest if./else if statement default to last else even if parameters above are true [duplicate]

I have a twofold question which involves something I would consider to be incorrect Javascript code.
How is the following statement interpreted in Javascript, and why?
(1,2,3,4)
Why is there a difference between these two invocations:
var a = (1,2,3,4);
a();
which leads to a being equal to 4 and Uncaught TypeError: a is not a function being thrown, and
(1,2,3,4)();
which leads to Uncaught TypeError: (((1 , 2) , 3) , 4) is not a function?
How is the following statement interpreted in Javascript, and why?
(1,2,3,4)
That's a comma operator expression (actually, a chain of them) wrapped in grouping parentheses. The comma operator is quite unusual: It evalutes both of its operands, then takes the value of the second one as its value, throwing away the value of the first one. You have a chain of them there, so the value of 1 is evaluated, then 2, then 3, then 4, and the result of the comma operator chain is the value 4; the result of the grouped parentheses expression is therefore 4.
Why is there a difference between these two invocations:
var a = (1,2,3,4);
a();
Because of the syntax of the language. In the first case, it's clearly not a function call, as there's no value prior to the first ( to call. The parsing rules for a complex language like JavaScript are just that: Complex. The parser is context-sensitive, and knows how to differentiate between grouping parentheses and function-call parentheses.
which leads to a being equal to 4 and Uncaught TypeError: a is not a function being thrown, and
(1,2,3,4)();
which leads to Uncaught TypeError: (((1 , 2) , 3) , 4) is not a function?
In both cases, the error message is quoting the expression that yielded the result it then tried to call as a function.
There is an operator in JS (among other languages) called the comma operator. It simply takes two operands, and returns the rightmost one.
a = 1, 2; // a now equals 2
It is, however, not the same comma as the function parameter separator. It is an operator.
The comma operator evaluates each of its operands (from left to right) and returns the value of the last operand.
So, the statement (1,2,3,4); returns 4, so var a = (1,2,3,4); means that a is equal to 4 which, is not a function, thus the error.
Likewise, (1,2,3,4) is just a grouping of comma operators and not a function, thus the second error.

Using ternary operators in a function with javascript

I am new to Javascript and sort of working through the weeds on these ternary operators. I have this small code segment:
const x = MSys.inShip ? 'ship launch' : '';
if (x != '') {send_command(x);}
While this works efficiently enough I am curious as to if it can be rewritten inside of the function call. Something like the following:
send_command(const x = MSys.inShip
? 'ship launch'
: MSys.alert("You aren't in your ship!);
This may not make sense with the current example but it's the best idea I had at the time. Basically, I like the shorthand of the ternary style for easy if/then conditionals but I don't like how it's tied to a variable which must then be called. I'm looking for a way to use that shorthand without having to tie to a variable.
Finally, the purpose of this is to see if you are in the ship and if you are, launch. If you aren't don't do anything at all or just send an alert message.
I am curious as to if it can be rewritten inside of the function call.
Yes, it can. But, if you do it there, then there is no need for a variable. You would be passing the function's argument directly inline.
Having said that, you can't pass that MSys.alert() statement as the "else" value because it will be executed in all cases. You'd have to pass a value there that the function can use as its input argument
send_command(MSys.inShip ? 'ship launch' : 'some other string');
Here's an example:
function foo(x){
console.log(x);
}
// If a random number is even, pass "even". If not, pass "odd"
foo(Math.floor(Math.random() * 10) % 2 === 0 ? "even" : "odd");
An important distinction between your two approaches - The second approach will ALWAYS call send_command() whereas your first approach will conditionally call it.
This distinction will matter depending on your implementation of send_command, but it sounds like you want the behavior of the first approach.
Additionally, You can't declare variables using const in a function call. If you just pass in the ternary operator, you will end up calling send_command with either your string, or undefined (the return of calling alert() ).
However, as an answer to your question, yes you can pass the ternary operator to a function like any other value. The ternary operator is an expression that will return a value.
Technically, you could keep a variable (such as operation) below, which references which method you want to execute, depending upon some conditional. And then you could pass that variable method the variable string it should get.
So, as you can see, it can be done. But look at how much complication was added to the process, rather than just using a simple if else statement.
function test_logic ( inShip ) {
// if they are in their ship, the operation should be the send_command method
// otherwise it should be the window alert
var operation = inShip ? send_command : window.alert;
function send_command ( command ) {
console.log( command );
}
// give the operation the desired string
operation( inShip ? 'ship launch' : "You aren't in your ship!" );
}
console.log( "Not in ship test" );
test_logic( false );
console.log( "In ship test" );
test_logic( true );

Behaviour of commas within parentheses in Javascript

I have a twofold question which involves something I would consider to be incorrect Javascript code.
How is the following statement interpreted in Javascript, and why?
(1,2,3,4)
Why is there a difference between these two invocations:
var a = (1,2,3,4);
a();
which leads to a being equal to 4 and Uncaught TypeError: a is not a function being thrown, and
(1,2,3,4)();
which leads to Uncaught TypeError: (((1 , 2) , 3) , 4) is not a function?
How is the following statement interpreted in Javascript, and why?
(1,2,3,4)
That's a comma operator expression (actually, a chain of them) wrapped in grouping parentheses. The comma operator is quite unusual: It evalutes both of its operands, then takes the value of the second one as its value, throwing away the value of the first one. You have a chain of them there, so the value of 1 is evaluated, then 2, then 3, then 4, and the result of the comma operator chain is the value 4; the result of the grouped parentheses expression is therefore 4.
Why is there a difference between these two invocations:
var a = (1,2,3,4);
a();
Because of the syntax of the language. In the first case, it's clearly not a function call, as there's no value prior to the first ( to call. The parsing rules for a complex language like JavaScript are just that: Complex. The parser is context-sensitive, and knows how to differentiate between grouping parentheses and function-call parentheses.
which leads to a being equal to 4 and Uncaught TypeError: a is not a function being thrown, and
(1,2,3,4)();
which leads to Uncaught TypeError: (((1 , 2) , 3) , 4) is not a function?
In both cases, the error message is quoting the expression that yielded the result it then tried to call as a function.
There is an operator in JS (among other languages) called the comma operator. It simply takes two operands, and returns the rightmost one.
a = 1, 2; // a now equals 2
It is, however, not the same comma as the function parameter separator. It is an operator.
The comma operator evaluates each of its operands (from left to right) and returns the value of the last operand.
So, the statement (1,2,3,4); returns 4, so var a = (1,2,3,4); means that a is equal to 4 which, is not a function, thus the error.
Likewise, (1,2,3,4) is just a grouping of comma operators and not a function, thus the second error.

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");

Javascript "tuple" notation: what is its point?

At wtfjs, I found that the following is legal javascript.
",,," == Array((null,'cool',false,NaN,4)); // true
The argument (null,'cool',false,NaN,4) looks like a tuple to me, but javascript does not have tuples!
Some quick tests in my javascript console yields the following.
var t = (null,'cool',false,NaN,4); // t = 4
(null,'cool',false,NaN,4) === 4; // true
(alert('hello'), 42); // shows the alert and returns 42
It appears to behave exactly like a semicolon ; separated list of statements, simply returning the value of the last statement.
Is there a reference somewhere that describes this syntax and its semantics? Why does it exist, i.e. when should it be used?
You are seeing the effect of the comma operator.
The comma operator evaluates both of its operands (from left to right) and returns the value of the second operand.
The resultant value when a,b,c,...,n is evaluated will always be the value of the rightmost expression, however all expressions in the chain are still evaluated (from left to right).
As already explained this behaviour is caused by , operator. Due to this the expression (null,'cool',false,NaN,4) will always evaluate to 4. So we have
",,," == Array(4)
Array(4) - creates new array with allocated 4 elements. At the time of comparison with the string this array is converted to string like it would be with Array(4).toString(). For arrays toString acts like join(',') method called on this array. So for the empty array of 4 elements join will produce the string ",,,".
Try this alert((null,'cool',false,NaN,4)) and then you can see.
demo
The reason is because the comma operator evaluates all the statements and return the last one.
Think of this line: a = 1, b = 2, c = 3; it will run each expression so in essence it will set the variables to what you want and return the last value (in this case 3)

Categories

Resources