javascript question mark ?: logical syntax, defensive programming - javascript

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

Related

Conditional function call without if

I used the following code a lot in my work
if (people === 'someone') {
doSomething();
}
Is there any shorter way to do it ?
You can write like this:
people === 'someone' && doSomething()
It means if the left side is true, then right side will be take into action. If the left side is false, the statement end.
Note: I agree with meagar , if is more readable.
And in case you interested in how the logic operator work, see this https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators
You can use ternary operator. A Standard Ternary is simple, easy to read, and would look like this:
$value = ($people === 'someone') ? doSomething() : 'nothing';
or
echo ($people === 'someone') ? doSomething() : 'nothing';

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

If true … else Shorthand

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.

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).

JSLint Expected '===' and instead saw '=='

Recently I was running some of my code through JSLint when I came up with this error. The thing I think is funny about this error though is that it automatically assumes that all == should be ===.
Does that really make any sense? I could see a lot of instances that you would not want to compare type, and I am worried that this could actually cause problems.
The word "Expected" would imply that this should be done EVERY time.....That is what does not make sense to me.
IMO, blindly using ===, without trying to understand how type conversion works doesn't make much sense.
The primary fear about the Equals operator == is that the comparison rules depending on the types compared can make the operator non-transitive, for example, if:
A == B AND
B == C
Doesn't really guarantees that:
A == C
For example:
'0' == 0; // true
0 == ''; // true
'0' == ''; // false
The Strict Equals operator === is not really necessary when you compare values of the same type, the most common example:
if (typeof foo == "function") {
//..
}
We compare the result of the typeof operator, which is always a string, with a string literal...
Or when you know the type coercion rules, for example, check if something is null or undefinedsomething:
if (foo == null) {
// foo is null or undefined
}
// Vs. the following non-sense version:
if (foo === null || typeof foo === "undefined") {
// foo is null or undefined
}
JSLint is inherently more defensive than the Javascript syntax allows for.
From the JSLint documentation:
The == and != operators do type coercion before comparing. This is bad because it causes ' \t\r\n' == 0 to be true. This can mask type errors.
When comparing to any of the following values, use the === or !== operators (which do not do type coercion): 0 '' undefined null false true
If you only care that a value is truthy or falsy, then use the short form. Instead of
(foo != 0)
just say
(foo)
and instead of
(foo == 0)
say
(!foo)
The === and !== operators are preferred.
Keep in mind that JSLint enforces one persons idea of what good JavaScript should be. You still have to use common sense when implementing the changes it suggests.
In general, comparing type and value will make your code safer (you will not run into the unexpected behavior when type conversion doesn't do what you think it should).
Triple-equal is different to double-equal because in addition to checking whether the two sides are the same value, triple-equal also checks that they are the same data type.
So ("4" == 4) is true, whereas ("4" === 4) is false.
Triple-equal also runs slightly quicker, because JavaScript doesn't have to waste time doing any type conversions prior to giving you the answer.
JSLint is deliberately aimed at making your JavaScript code as strict as possible, with the aim of reducing obscure bugs. It highlights this sort of thing to try to get you to code in a way that forces you to respect data types.
But the good thing about JSLint is that it is just a guide. As they say on the site, it will hurt your feelings, even if you're a very good JavaScript programmer. But you shouldn't feel obliged to follow its advice. If you've read what it has to say and you understand it, but you are sure your code isn't going to break, then there's no compulsion on you to change anything.
You can even tell JSLint to ignore categories of checks if you don't want to be bombarded with warnings that you're not going to do anything about.
A quote from http://javascript.crockford.com/code.html:
=== and !== Operators.
It is almost always better to use the
=== and !== operators. The == and != operators do type coercion. In
particular, do not use == to compare
against falsy values.
JSLint is very strict, their 'webjslint.js' does not even pass their own validation.
If you want to test for falsyness. JSLint does not allow
if (foo == null)
but does allow
if (!foo)
To help explain this question and also explain why NetBeans (from) 7.3 has started showing this warning this is an extract from the response on the NetBeans bug tracker when someone reported this as a bug:
It is good practice to use === rather than == in JavaScript.
The == and != operators do type coercion before comparing. This is bad because
it causes ' \t\r\n' == 0 to be true. This can mask type errors. JSLint cannot
reliably determine if == is being used correctly, so it is best to not use ==
and != at all and to always use the more reliable === and !== operators
instead.
Reference
Well it can't really cause problems, it's just giving you advice. Take it or leave it. That said, I'm not sure how clever it is. There may well be contexts in which it doesn't present it as an issue.
You can add this to the previous line to disable these warning.
// eslint-disable-next-line

Categories