I just saw this construction for the first time in javascript
if (someConditionIsMet && !(anotherCondition && oneMoreCondition)) {
return something
}
There is a !() inside of the if-conditional statement. I'm wondering what exactly that does. Is it just a way of grouping several conditions together and making sure they all evaluate a certain way before triggering logic? If so, is this merely to simplify the appearance or is there some logical advantage here?
Specifically for !(anotherCondition && oneMoreCondition), it means NOT (anotherCondition AND oneMoreCondition).
This is De Morgan's laws:
not (A and B) = not A or not B
Some might say that not A or not B is easier to read than not (A and B) but that's personal preference.
Expanding the whole condition using De Morgan's law would result in:
someConditionIsMet AND (NOT anotherCondition OR NOT oneMoreCondition)
in Javascript:
if (someConditionIsMet && (!anotherCondition || !oneMoreCondition))
You can use that expanded form if you think it's more readable.
!() In any case in javascript means that if they are NOT true. So basically like in this case...
if(!(anotherCondition && oneMoreCondition)) {
Console.log("If both set to false this would run!");
}
if anotherCondition and oneMoreCondition were both set to false this would actually return true. This here might help you: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_NOT_!
It's evaluating the condition of anotherCondition && oneMoreCondition, and then reversing it.
So if the condition evaluates to true, the ! makes the condition evaluate to false.
Related
I've recently become informed of the ternary operator and it seems like an effective way of cleaning up my code. However, I seem to be confused with the possibilities of it.
I understand that you cannot use it for if-only conditions, but I'm a little confused about the logic of what I've done.
I wrote this:
if(current_slide < 1){
current_slide = 1;
ToggleEnabled(next_button);
}else if(current_slide > total_slides){
current_slide = 1;
ToggleEnabled(prev_button);
}
It works, whatever. I wanted to clean it up a little, so I made this:
current_side < 1 ? (ToggleEnabled(next_button), current_slide = 1) : current_slide > total_slides ? (ToggleEnabled(prev_button), current_slide = 1) : [No clue what to put here];
Is there a better way of doing this in a more tidy way, or should I just keep using the if-elseif- ?
In my opinion the ternary operator should not be chained. As #VLAZ expressed their concerns in their comment, the ternary can become excessively difficult to read if you chain it in multiples. In this situation I would stick with the traditional if-else.
Take a look at the following:
if (condition1) {
// do stuff #1
} else if (condition2) {
// do stuff #2
} else if (condition3) {
// do stuff #3
} else {
// do stuff #4
}
And compare the readability to the same in ternary (I tried to indent it clearly, but chained ternary formatting is a matter of opinion):
condition1
? // do stuff #1
: condition2
? // do stuff #2
: condition3
? // do stuff #3
: // do stuff #4
To my eye the first option is a lot more readable. There is not much to be gained even if you would understand chained ternary very well, as it is (slightly) less efficient than traditional if-else.
Also of note should be the fact that ternary always needs the both the ? and the :, which means there is always a "final else" that you must deal with.
IMO, the ternary operator is meant to choose between answers or values, based on a condition, e.g.:
const x = condition1 ? 1 : 2;
return condition2 ? func1(x) : func2(x);
If you don't use the resulting value from a ternary expression (as you do) then the usage becomes highly suspect to me, and I would most likely ask it to be changed in code review. Even more so if you move the assignment part to BEHIND the ? and : selectors as you did.
Not everything that is possible, is also good style, good practice or recommended.
I found the following in a code example at datatables.net.
return value > 20 ? true : false;
Why wouldn't they have just written
return value > 20;
Could the latter return values other than true or false? Trying to figure out whether they were maybe just thinking the code was more readable this way, or whether there is actually a significant reason for doing this that I'm not aware of.
The only possible result is true or false. I don't think it makes it more readable. The only reason they may have done it that I can think of is that they were a new developer and didn't realize value > 20 was valid to return.
This is along the same lines as someone writing this:
if(value > 20 === true){ . . . }
Which is unnecessary because if conditions are implicitly compared against their "truthy-ness". The statement should be:
if(value > 20){ . . . }
As such, in your example, the code should just be:
return value > 20;
Because (as you correctly surmize) a greater-than/less-than expression can only result in true or false.
Now, if someone wanted to return an alternate set of binary results, then you could see something like this being used:
return value > 20 ? "acceptable" : "unacceptable";
Ok, while I was nesting some validation if, I've come into something about performance.
Let's suppose I'm validating a ticket to a show, I can do something like this:
var validateVipTicket = function (ticketInfo) {
if (ticketInfo.isPaid) {
if (ticketInfo.isOver16) {
if (ticketInfo.isVip) {
return true;
} else return 'Not Vip';
} else return 'Not old enought';
} else return 'Need to pay first';
};
And call it like this validateVipTicket({isPaid: true, isOver16: true, isVip: true});
BUT
let's suppose that does not matter to specify what error happened, I just want a true or false, then, what approach would be faster?
if (ticketInfo.isPaid) {
if (ticketInfo.isOver16) {
OR
if (ticketInfo.isPaid && ticketInfo.isOver16) {
On the first case, the first property will be checked and, when it finishes, the second property will be checked. On the second case, the first property will be checked, the second property will be checked and, them, both properties will be compared against each other. Is this right? Am I missing something? Which is faster and why?
On the second case, the first property will be checked, the second
property will be checked and, them, both properties will be compared
against each other. Is this right?
No, that's actually not right. The && operator does a short-circuit evaluation, which means that the second operand is never evaluated if the first operand evaluates to false.
That makes the two approaches exactly equivalent (even if there were any side effects of evaluating the oparands). As they do exactly the same amount of work in the same way, you can expect the performance to be very similar. It's even likely that the approaches end up generating the same executable code in the end.
It makes no difference:
if ( a && b )
is the same as
if ( a )
if ( b )
In the case of a && b, as soon as a is found false, then it does not matter what b is.
What happens at the CPU instruction level in both cases is:
cmp [a], 0 ; a == 0? (it does this by calculating a - 0)
jz false1 ; jump if result is zero
; a is true
cmp [b], 0
jz false2
; both a and b are true
Whether 3 different messages are returned, or just 1, could make a difference in speed, depending on how it is compiled. In this example, it makes no difference:
false1: return "not a!";
false2: return "not b!";
just_false: return false;
But here, an extra jump/goto is involved:
false1: result = "not a!"; goto done;
false2: result = "not b!"; // goto done optimized away
done: return result;
The 2 statements are equivalent in terms of performance. In both cases the second check (ticketInfo.isOver16) will be evaluated only if the first check (ticketInfo.isPaid) has returned true. Both statements are absolutely the same in terms of speed. So you should prefer the one that's more readable to you.
The performance in modern JS Engines such as V8 would be the same. Although there is always the chance that a crappy interpreter performs one better than the other but with modern browsers and JIT compilers such as V8 you should get the same results.
Proof of concept:
http://jsperf.com/nested-conditionals-vs-inline
How to execute the if statement only when both the inputs are different not when both inputs are same.
suppose:
var a=prompt("have Input","");
var b=prompt("have Input","");
if(a && !b){alert("ok")}
else{"wrong"}
the above condition works when both the inputs are true ,when both the inputs are false and when a is true and b is false but if a is false and b is true the if statement dont get executed .How to solve this issue through if statement.What is the way to get my problem solved?
if you need that a and b would be different isn't if (a != b) enough?
It sounds like you are looking for a logical exclusive-or (XOR) operation. There are some Javascript examples here. My favorite (for being unexpected and simple) is:
if (foo ? !bar : bar) {
...
}
Admittedly, this is a little unusual coding, and verges on being "too clever". Sometimes if a language does not have direct syntax for an operation the code just has to be verbose, like getting the quotient and remainder from a division operation.
if( a===b)
{
"Wrong"
}
else
{
alert("Ok");
}
So I'm using a shorthand JavaScript if/else statement (I read somewhere they're called Ternary statements?)
this.dragHandle.hasClass('handle-low') ? direction = "left" : direction = "right"
This works great, but what if later I want to use just a shorthand if, without the else portion. Like:
direction == "right" ? slideOffset += $(".range-slide").width()
Is this possible at all?
you can use && operator - second operand expression is executed only if first is true
direction == "right" && slideOffset += $(".range-slide").width()
in my opinion if(conditon) expression is more readable than condition && expression
Don't think of it like a control-block (ie: an if-else or a switch).
It's not really meant for running code inside of it.
You can. It just gets very ugly, very fast, which defeats the purpose.
What you really want to use it for is ASSIGNING VALUES.
Taking your initial example and turning it on its head a little, you get:
direction = (this.dragHandle.hasClass("handle-low")) ? "left" : "right";
See. Now what I've done is I've taken something that would have required an if/else or a switch, which would have been used to assign to that one value, and I've cleaned it up nice and pretty.
You can even do an else-if type of ternary:
y = (x === 2) ? 1 : (x === 3) ? 2 : (x === 4) ? 7 : 1000;
You can also use it to fire code, if you'd like, but it gets really difficult after a while, to know what's going where (see the previous example to see how even assignment can start looking weird at a glance)...
((this.dragHandle.hasClass("...")) ? fireMe(something) : noMe(somethingElse));
...this will typically work.
But it's not really any prettier or more-useful than an if or a branching, immediately-invoking function (and non-JS programmers, or untrained JS programmers are going to crap themselves trying to maintain your code).
The conditional operator is not a shorthand for the if statement. It's an operator, not a statement.
If you use it, you should use it as an operator, not as a statement.
Just use a zero value for the third operand:
slideOffset += direction == "right" ? $(".range-slide").width() : 0;
What you have will not work, but why not just use a one line if statement instead.
if(direction == "right") slideOffset += $(".range-slide").width();
This involves less typing than the method Ray suggested. Of course his answer is valid if you really want to stick to that format.
No, This is not possible, because ternary operator requires, three operands with it.
first-operand ? second-operand (if first evaluates to true) : third-operand (if false)
you can use && operator
direction == "right" && slideOffset += $(".range-slide").width()
This doesn't exactly answer your question, but ternaries allow you to write less than you've shown:
direction = this.dragHandle.hasClass('handle-low') ? "left" : "right";
And now that I think about it, yeah, you can do your question too:
slideOffset + direction == "right" ? = $(".range-slide").width() : = 0;
This is a theory. The next time I have an opportunity to += a ternary I will try this. Let me know how it works!
You can use this shorthand:
if (condition) expression
If in some cases you really want to use the if shorthand. Even though it may not be the best option, it is possible like this.
condition ? fireMe() : ""
Looks weird, does work. Might come in handy in a framework like Vue where you can write this in a template.
You can using Short-circuit Evaluation Shorthand. if you want the if condition just write the else condition.
let
a = 2,
b = a !== 2 || 'ok';
console.log(b);