If true … else Shorthand - javascript

I know that the normal use case for this if statement is e.g.
var string = boolean ? "this" : "that";
I use jhint in my editor and when i try something like
boolean ? array.push("this") : array.slice("that",1);
jshint throws (W030) "Expected an assignment or function call and instead saw an expression"
So far the code always worked fine but maybe i was just lucky.
So my question is, why should i not use this pattern and what would be an alternative? Because writing
if(boolean){
array.push("this");
} else {
array.splice("that",1);
}
for such short instructions really give me the creeps.
thank you.

It is possible to wrap the ternary operator inside the void operator like this:
void(cond ? expr1 : expr2);
This achieves the desired result and passes JSHint. See JSFiddle and click JSHint button.
However, I recommend the following syntax:
if (cond) {
expr1;
} else {
expr2;
}
Because it is more readable. Just because JavaScript lets you do strange things does not mean that you should.

What it complains about is you misappropriating the conditional operator. It is an operator not a control structure. So it lives in the category of such things things as +,-,*,/. That means you expect the first operand to be a boolean and the second and third to yield a return value.
The whole thing is meant to be short for
if (boolean) {
string ="this" ;
} else {
string ="that";
}
It wants to return a value (which it can't in your case) and it expects you to use that value (which you don't). So the tenary if is not the thing to use for your case and as a result makes it far less readable.

You are using side effects in expressions to execute logic.
Indeed not very friendly code. It will work.
Just rewrite to distinct logic from expressions.

You can circumvent the jshint message using:
void(boolean ? array.push("this") : array.slice("that",1));

If you really want to use the ternary operater for this kind of operation in a clean way, then you can do it like this:
array[cond ? 'push' : 'slice'](cond ? "this" : "that", cond ? 1 : undefined);
or
array[cond ? 'push' : 'slice'].apply(null, cond ? ["this"] : ["that", 1]);
But anyway you may prefer a boring if statement.

Related

Do I need to use an "=" when using the ? : javascript shortcut?

Can someone tell me if this is valid javascript to do this:
if (wf.statusId == Status.Dirty) {
wf.createdDate
? promises.push(self.wordFormUpdateSubmit(wf, key))
: promises.push(self.wordFormAddSubmit(wf, key));
}
Would there be cases where this would not work correctly if createdDate was not defined?
Here's what this replaced:
if (wf.statusId == Status.Dirty) {
if (wf.createdDate) {
var updatePromise = self.wordFormUpdateSubmit(wf, key);
promises.push(updatePromise);
} else {
var addPromise = self.wordFormAddSubmit(wf, key);
promises.push(addPromise);
}
}
Also a related question. Would it be possible to use the same syntax with ? : to replace the need for the if () { } construct ?
Using = with ternary operator is not mandatory unless expr1 and expr2 are returning something and you want to save it in some other variable.
In your case, unless promises.push(self.wordFormAddSubmit(wf, key)) and promises.push(self.wordFormUpdateSubmit(wf, key)) are returning something that you want to save it a variable, there is no need for a =.
if (wf.statusId == Status.Dirty) {
promises.push(self[wf.createdDate ? 'wordFormUpdateSubmit' : 'wordFormAddSubmit'](wf, key));
}
wf.createdDate only true if it is not undefined or have value. so this should work fine.
if (wf.statusId == Status.Dirty) {
wf.createdDate
? promises.push(self.wordFormUpdateSubmit(wf, key))
: promises.push(self.wordFormAddSubmit(wf, key));
}
Regards
Mk
This is an example of a ternary statement, using the conditional (ternary) operator, which by definition replaces an if...else construct.
From MDN:
The conditional (ternary) operator is the only JavaScript operator that takes three operands. This operator is frequently used as a shortcut for the if statement.
[source]
Both of your code samples would work the same way, ie if createdDate was undefined the second expression of your ternary statement would run (the line after the :) just like the else block of your if...else construct would run.
The title question seems somewhat unrelated, in that you would only need to use = if you wanted to save a reference to something. In this case, it does not appear that you do.
As for your follow-up question, plenty of people use ternary statements for small checks and tasks that fit on one or a few lines (I personally don't because I prefer the readability of if...else), however anything even moderately complex can quickly make your code hard to read and understand. But yes, technically, ternary statements can replace if...else blocks.
regarding the second question:
assuming you don't need to save the results in a variable, you can do:
promises.push(wf.createdDate?
self.wordFormUpdateSubmit(wf, key) :
self.wordFormAddSubmit(wf, key);
);
and even this works:
promises.push(
(wf.createdDate? self.wordFormUpdateSubmit:self.wordFormAddSubmit)(wf, key)
);

Javascript best practice to use undefined as boolean evaluation?

In this simple javascript code, method verify returns a string if conditions do not match, else undefined. I am using undefined value in 'if' clause. Is this common / acceptable javascript programming practice?
if (verify(text)) {
alert(text + " is not bar");
}
function verify(foo) {
if (foo + "" != "bar") return "foo is not same as bar";
}
Yes, since you know the verification outcomes will be either truthy (a non-empty string) or falsy (undefined), it's perfectly fine to use it like that.
Here's a list of truthy and falsy values in JS, you might find them handy: http://www.sitepoint.com/javascript-truthy-falsy/
It is a common practise but in my experience its better to be explicit. For instance, I prefer:
verify(text) === undefined
The way I would suggest is to make the 'verify' to return a boolean value. The reason for this, is if for whatever reason you have a verification method that returns 0 (zero) and you do if (verify), the condition will be false but 0 is actually a verified value.
I hope that helps.
Although this is technically possible and works fine in most cases, I personally find it better style to design functions so that they always return the same type. My IDE warns me about inconsistent functions:
and this warning should be taken seriously. In particular, it helps you avoid unpleasant surprises when you test your app:
// hmm...
function isZero(n) {
if(n == 0)
return true;
}
// let's test it
describe("test", function() {
it("isZero", function() {
expect(isZero(0)).toBe(true);
expect(isZero(1)).toBe(false); // FAILURE!
});
});

Shorthand if ? return : null

I want to achieve this:
if (full) {
return
}
else{
// nuthin
}
But shorter, something like:
full ? return : null;
But that doesn't work..
I could do:
if (full) { return }
But I like the ternary more
I expected something like full ? return to work...
I basically want to break out of the current function when the value is true...
Are there any better/working shorthands available?
The arguments of a ternary are expressions not statements.
return; is a statement so what you're proposing is not syntatically valid.
Your if statement is about as terse as you can make it: especially if you remove unnecessary braces.
Explainations
If you only want the test if true, you can use the logical AND operator && like so:
index.js:
(function(){
var full=true;
full&&alert('Glass is full');
})();
Note that in this example, nothing will happen in case var full=false;.
Source-code
JSFiddle source-code.
Codepen source-code
Pastebin source-files
So this is as short as it gets:
if full return
For those using typescript with all the bells and whistles:
if (condition) return;

javascript question mark ?: logical syntax, defensive programming

I am trying to re-write the statement below using the javascript ?: syntax.
if(type of someVariable !="undefined"){
someFunction(someVariable);
}else{}
This is my current attempt and it's causing a syntax error
typeof someVariable != "undefined" ? someFunction(someVariable) : ;
If any one can tell met what I'm doing wrong I'd appreciate it. Any accompanying tips on best practices for defensive programing are welcome.
?: style (requires expressions on either side of the :):
typeof(someVariable) != 'undefined' ? someFunction : null;
Ninja-style:
someVariable !== undefined && someFunction(someVariable);
[Edit: I couldn've sworn noop was a thing in Javascript, but apparently I was wrong. Switched to null]
even though the ternary operation controls the program flow, I'd use it only in assignment operation or when returning a value from a function.
check this out:
Benefits of using the conditional ?: (ternary) operator
It should look like this.
someVariable != undefined ? someFunction(someVariable):someOtherfunction(someOtherVarialbe);
if you do not want else statement and want it in single line you can do like this:
if(someVariable != undefined){someFunction(someVariable);}

JavaScript: Error - "Expected an assignment or function call and instead saw an expression"?

I am using JSLint to ensure my JavaScript is "strict" and I'm getting the following error:
Expected an assignment or function call and instead saw an expression
On the following code:
(my_var > 0 ) ? $("#abc").html(my_array.join('')) : $("#abc").html('<h2>Hello ' + persons_name);
Any ideas why I'm getting such an error? Also, I'm using jQuery as seen in the above code, in case that makes a difference.
My guess would be that JSLint is unhappy since you're using the ternary operator, and you're not doing anything with the value. Refactoring this into the equivalent:
if (my_var > 0 ) {
$("#abc").html(my_array.join(''));
} else {
$("#abc").html('<h2>Hello ' + persons_name);
}
would eliminate the error. If for some reason you're really attached to using the ternary operator, the "right" way to use it would be:
$("#abc").html((my_var > 0) ? my_array.join('') : '<h2>Hello ' + persons_name);
I believe this is because the ternary operator evaluates the expression and returns a value that is expected to be assigned. For example:
var test = (my_var > 0) ? true : false;
However, you are using it like a regular if/then/else statement. While the ternary operator does perform if/then/else, it is traditionally used in assignents.
EDIT: As an addendum: would this statement make sense to you?
var foo = 1;
(my_var > 0) ? true : false;
console.log('hello world');
you are using an expression (an expression using the ternary operator to be precise) in a single line: your line is comprised uniquely of an expression.
this is considered poor programming practice in many language, and could be rewritten using an if statement to render this line more clear.
Just asked the same Q without finding this one for some reason...
The ternary returns a value that isn't being used so you're abusing the ternary structure by not using the value (even though the function calls are being made as intended).

Categories