Ternary Operators as short conditional statements - javascript

Is there anything wrong with using ternary operators in place of longer conditional statements in Javascript, for instance using:
(variable == "dog") ? dog_stuff() : false;
Rather than
if ( variable == "dog" )
{
dog_stuff();
}
This may sound like a stupid question but I just find it's pretty quick and easy to read, I just don't want to be using it if there's a possible drawback?

You could also write
(variable == 'dog') && dog_stuff();
if you don't have an else statement.
A few lines from backbone.js:
options || (options = {});
models = _.isArray(models) ? models.slice() : [models];
model = this.getByCid(models[i]) || this.get(models[i]);
You can group multiple statements, if it's very necessary:
(1==1) && (a=2,b=3)
alert(a); // 2
alert(b); // 3

It's wrong because you're telling your code to execute false. Imagine the following code:
if ( variable == "dog" )
{
dog_stuff();
} else {
false;
}
IMO the 4 line conditional function call is perfectly fine. You can shorthand it to:
if (variable == "dog") dog_stuff();
The only problem with this is if you comment it out, or add 1 more function then things look correct, but don't execute correctly:
if (variable == "dog") dog_walk(); dog_bark(); // dog_bark executes always!
if (variable == "dog") // dog_walk();
earn_cash(); // suddenly earn_cash() is dog-dependent.

As long as the format is easily understood by you and anyone else that may need to read the code, it's fine.

Related

If else if shortening

I can see there are so many related questions to this. Could not find anything specific addressing my query. Here is my question:
How can i shorten the below if else condition:
If (condition1)
{
If(condition2)
{
Logic A
}
}
Else if (condition3)
{
Logic A
}
One way i could come up was as below:
If (condition1 && condition2 || !condition1 && condition3)
{
Logic A
}
Just wondering if there is a better way of doing it?
In this case optimization is important only from readability point of view. From OP examples I would prefer original one, because it easier to follow for developer/reader who didn't write this code.
We execute one action or do nothing based on conditions, so I would wrap every condition chain which leads to the execution into the method with descriptive name and used them with or operator.
// condition 1 = customer.persisted
// condition 2 = bonuses.has(customer.id)
// condition 3 = promotionCodes.has(customer.promotionCode)
function whenExistingCustomerWithBonus() {
return customer.persisted && bonuses.has(customer.id);
}
function whenGuestCustomerWithPromotionCode() {
return customer.persisted === false && promotionCodes.has(customer.promotionCode);
}
// Usage
if (whenExistingCustomerWithBonus() || whenGuestCustomerWithPromotionCode()) {
// execute logic A
}
you can do this
(condition1 && condition2 || !condition1 && condition3) ? logic(a) : logic(b)
Its called Ternary operator, It would make your code shorter and you can also use it to set a variable, for example
const isTrue = 4 > 3 ? true : false
There are some aspects that you must keep in mind.
It's possible that a shorter code be faster in some script languages (like JavaScript, PHP...).
But it worth? Is your if inside a loop long enough to make any difference in your code execution time?
Do your shortened code makes easier or harder to understand your code? Sometimes joining some if conditions inside a boolean logic makes it easier to understand, but sometimes it's so complicated that is very hard to understand.
sometimes its possible to simplify (note the use of the word 'simplify' instead of 'shorten') conditional logic by reversing it, or by delegating logic to other functions, or a combination of both:
given this:
function performLogic() {
if (condition a) {
if (condition b) {
logic 1
}
} else {
logic 1
}
}
let's try to think about this in reverse:
function performLogic() {
if (!condition a) logic 1
else if (conditoin b) logic 1
}
keep in mind this kind of refactor will not always be possible, and i also advise you to write unit tests for the logic to ensure that the end result remains the same.
It can also sometimes be simplified further depending on the logic in the function. many times we can replace conditional logic with guard clauses like this:
function getSomeValue() {
if (condition a) {
if (condition b) {
... do some logic
return someValue;
}
}
}
this can be changed to
function getSomeValue() {
if (!condition a) return;
if (!condition b) return;
... do some logic
return someValue;
}

JS OR statement just not working

I know this question has been asked a million times but I've gone through just about every method suggested in other threads and cannot seem to figure out why the OR statement in my IF is not working. And would like some explanation as to how to use the OR function if I am doing this completely wrong.
I have the following code
if((a != 'error') || (a != 'stay')) {
//Do something here
}
And regardless if the a is error or stay the code is being executed anyway
I have also tried
if((!a == 'error') || (!a == 'stay')) {
//Do something here
}
And without brackets, but noting seems to work.
Thanks in advance
Your condition is a tautology. It's true no matter what the value of a is. If a is 'error' then a is not 'stay' and vice versa. It seems like what you want is
if (a != 'error' && a != 'stay') { /* ... */ }
You are including the (!) sign together in the brackets which is an error and will not make the logical operator work. You need to put the (!) sign outside and before the bracket. Check this code below for more clarity.
var a = "hello";
var b = "stay";
var c = "error";
if(!(a == 'error') || !(a == 'stay')) {
console.log("Hello");
};
for best practice, you should have it like this
var a = "hello";
var b = "stay";
var c = "error";
if(!(a == 'error' || a == 'stay')) {
console.log("Hello");
};

nested if statement in one line

if(something.food == true){
if(something.food.fruit == 'apple' || something.food.fruit == 'mango'){
//do something
}
}
this is clear where food must be true later check it's child object, but how to write this in one line? I mean with single if.
If something.food is true then it can not be an object containing fields as well. Though your current check does check for a "truthy" value, it reads quite strange (thanks for pointing this out T. J. Crowder). Instead you should just leave out the == true part.
The resulting check is:
if (something.food && (something.food.fruit == 'apple' || something.food.fruit == 'mango') {
//do something
}
That's all
if(something.food && (something.food.fruit == 'apple' || something.food.fruit == 'mango')) {
//do something
}
As a petition in the comments, I will explain that.
First we check something.food without == true because we need to check if it exists. Then wrap the rest of code into parenthesis and the expression will run ok

Shorthand for if sentence

Why I am asking
I have been having a lot of trouble understanding the shorthand for the if sentence in JavaScript, and I haven't found an article or tutorial that described it well. And that's why I am stuck opitimizing my little code. And I am new to JavaScript, so if someone could give me a basic understanding of the shortning of this code, I would very much appreciate you telling me the magic behind the code.
What I need help with
I am going to use the exact same code in a lot of functions. Therefore, I want to optimize it and make it shorter version of the code.
function welcomemessage() {
if (br == 1) {
hello();
}
else {
hey();
}
}
Use the ternary operator.
function welcomemessage() {
(br == 1) ? hello() : hey();
}
The ternary operator is useful, and not difficult to understand. here's how it works.
(condition) ? (true) : (false)
Edit:
Since JS treats functions as first class objects, it is possible to create a wrapper. Something like below (not tested though)
function ternaryWrapper(br, functionTrue, functionFalse){
return (br == 1) ? functionTrue : functionFalse;
}
//call it
ternaryWrapper(2,hello, hey);
Even shorter:
function welcomemessage(br){
[hello,hey][br-1](); //This will work.
}
welcomemessage(1); //hello();
welcomemessage(2); //hey();
Fun Fact:1
To make your script hard to read for someone else, do it like this:
function welcomemessage(){
return br==1 && (hello(),1) || (hey(),1); //This will work too.
}
1 Totally not related to the answer.
Update
var something = ( (br == 1) ? hello() : hey() );
something will be the value hello() or hey() returned.
Or:
var msgfuncs = [ hey, hello ];
function welcommessage() { msgfuncs[br](); }
(assumes that when "br" isn't 1 it's 0, which of course may be an invalid assumption.)
If the choice is made with different functions, just put the array directly in the surrounding function:
function welcomemessage() {
[ hey, hello ][br]();
}
If you want to make the decision and save the function to call later, you can do this:
var messageFunction = [ hey, hello ][ br ];
then any time later:
messageFunction();
In case br is always be numeric, the xbonez answer can be optimized a little bit by using strict comparison === (because it is a little bit faster):
function welcomemessage() {
(br === 1) ? hello() : hey();
}
And another interesting option is:
function welcomemessage() {
(br - 1) ? hey() : hello();
}
This last function works because when br is 1, it will turn to 0 (which is a falsish value) and evaluate to false, triggering hello(), and for the rest it will trigger hey()

Javascript OR in an IF statement

I am trying to make an if statement in javascript that will do something if the variable does not equal one of a few different things. I have been trying many different variations of the OR operator, but I cant get it to work.
if(var != "One" || "Two" || "Three"){
// Do Something
}
Any ideas? Thanks!
Update:
I have tried this before:
if(var != "One" || var != "Two" || var != "Three"){
// Do Something
}
For some reason it does not work. My variable is pulling information from the DOM i dont know if that would effect this.
Actual Code
// Gets Value of the Field (Drop Down box)
var itemtype = document.forms[0].elements['itemtype' + i];
if(itemtype.value != "Silverware" || itemtype.value != "Gold Coins" || itemtype.value != "Silver Coins"){
// Do Something
}
Your expression is always true, you need:
if(!(myVar == "One" || myVar == "Two" || myVar == "Three")) {
// myVar is not One, Two or Three
}
Or:
if ((myVar != "One") && (myVar != "Two") && (myVar != "Three")) {
// myVar is not One, Two or Three
}
And, for shortness:
if (!/One|Two|Three/.test(myVar)) {
// myVar is not One, Two or Three
}
// Or:
if (!myVar.match("One|Two|Three")) {
// ...
}
More info:
De Morgan's Laws
Edit: If you go for the last approaches, since the code you posted seems to be part of a loop, I would recommend you to create the regular expression outside the loop, and use the RegExp.prototype.test method rather than String.prototype.match, also you might want to care about word boundaries, i.e. "noOne" will match "One" without them...
Assuming you mean "val does not equal One or Two or Three" then De Morgan's Theorem applies:
if ((val != "One") && (val != "Two") && (val != "Three")) {
// Do something...
}
For a shorter way to do it, try this format (copied from http://snook.ca/archives/javascript/testing_for_a_v):
if(name in {'bobby':'', 'sue':'','smith':''}) { ... }
or
function oc(a)
{
var o = {};
for(var i=0;i<a.length;i++)
{
o[a[i]]='';
}
return o;
}
if( name in oc(['bobby', 'sue','smith']) ) { ... }
The method mentioned by Mike will work fine for just 3 values, but if you want to extend it to n values, your if blocks will rapidly get ugly. Firefox 1.5+ and IE 8 have an Array.indexOf method you can use like so:
if(["One","Two","Test"].indexOf(myVar)!=-1)
{
//do stuff
}
To support this method on IE<=7, you could define a method called Array.hasElement() like so:
Array.prototype.hasElement = function hasElement(someElement)
{
for(var i=0;i<this.length;i++)
{
if(this[i]==someElement)
return true;
}
return false;
}
And then call it like so:
if(!["One","Two","Three"].hasElement(myVar))
{
//do stuff
}
Note: only tested in Firefox, where this works perfectly.
In addition to expanding the expression into three clauses, I think you'd better name your variable something other than var. In JavaScript, var is a keyword. Most browsers aren't going to alert you to this error.
Alternate way using an array:
var selected = ['Silverware', 'Gold Coins', 'Silver Coins'];
if ( selected.indexOf( el.value ) != -1 ) {
// do something if it *was* found in the array of strings.
}
Note: indexOf isnt a native method, grab the snippet here for IE:
https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Array/IndexOf

Categories