Using '&&' as a shorthand if statement? - javascript

While I was killing time looking up Javascript shorthand patterns, I came across an interesting way of expressing an if statement here. The following works:
​var var1 = 5;
var var2 = 1;
var1 == 5 && var2++;
I think that's a totally cool (and shorter, cleaner) way of writing an if statement that only needs to do one operation. However, I ran into an issue with the following code as soon as I tried something else with it:
​var var1 = 5;
var var2 = 1;
var1 == 5 && var2 = 2;
Instead of working like the first code snippet, my test throws an error:
Uncaught ReferenceError: Invalid left-hand side in assignment
Why doesn't this work, and why is the left-hand side of my statement being called out as incorrect as opposed to the right hand?

This doesn't work because the && operator has higher precedence than the = operator. In other words, your code is interpreted like this:
(var1 == 5 && var2) = 2;
If you manually put parentheses around the assignment, it will be interpreted correctly.
var1 == 5 && (var2 = 2);
Other people will reprimand you for writing code like this, saying that is a bad idea because it makes the intent of the code harder to read--which is true, especially for people unfamiliar with this idiom--but it is important to try it out and experiment with things like this to see for yourself what happens. You've already encountered one of the annoying things about this approach.
Anyway, in cases like this, I personally prefer to use single line if statements, like this
if(condition) statement;
Although I'm sure others will tell you that that's bad style because you have to manually add brackets when you need more statements, this hasn't really bit me and IMO it's cleaner than using three lines just for a simple condition, like you said.

Don't be alarmed that this doesn't work as you'd expect, in fact less than a month ago Brendan Eich (Creator of JavaScript) was sharing with us that this type of use is better known as an "abusage" of the language, since this logical operator isn't meant to execute code like this, but rather it's meant to determine the value of an expression.
"I also agree...that the && line is an abusage, allowed due to JS’s C heritage by way of Java, but frowned upon by most JS hackers; and that an if statement would be much better style..." http://brendaneich.com/2012/04/the-infernal-semicolon/
That being said, you can avoid the operator precedence issue by wrapping your statements:
(var1 == 5) && (var2 = 2)

because you are using an invalid operator on the right-hand side. its trying to read the entire statement as a single variable.

Is
var1 == 5 && var2++;
an cleaner or more understandable than this?
var2 += var1 === 5 ? 1 : 0;
In addition, the above expresses intent far more clearly than your code: the next guy who has to look at your code will see it and understand immediately what's going on, but looking at your code:
var1 == 5 && var2++
Is going to raise red flags in her head, because it looks like a bug or a some sort of typo — which means she's going to have to spend time trying to understand what you were actually trying to accomplish and whether or not the wonky code was intentional or not.
My first reaction, looking at
var1 == 5 && var2++ ;
Is that an assignment was intended:
var1 = 5 && var2++ ;
But the developer bounced the = key by accident, turning it into an orphaned expression (that happens to have side-effects).
Further, orphan expressions like that is likely to get flagged by any decent linter, for instance eslint's no-unused-expressions rule, as they indicate a probable bug.

Or
You could try using the ternary operator to make your code look concise.
When utilizing the '&&' operator fail or throw errors, I default back to the ternary operator.
Example:
let var1 = (conditional) ? "on true return" : "on false return";

Related

What is the reason behind var a = (expression1, expression2) in javascript?

Looking through some JS code I have found something like this:
var a, b;
if (
(a = someFunction1(), b = someFunction2() )
){
...
}
I never found anything like this previously and I do not understand the reason for doing something like this. Therefore I am curious: is the person who has done this out of his mind or am I just not capable to understand his idea.
When I try to check what construct like (expression1, expression2) does, I see that it always returns the value of the second expression:
(5, 6) // 6
('strange', 'things') // 'things'
(4, undefined) // undefined
So if I would be the one writing this code, I would do something like this:
var a = someFunction1(),
b = someFunction2();
if (b){ ... }
Am I correct in my reasoning?
When I try to check what construct like (expression1, expression2) does, I see that it always returns the value of the second expression
Yes. Even without trying out, this is what the comma operator does.
Am I correct in my reasoning?
Yes. Your code does exactly the same thing, but is more readable.
You are correct, that is essentially if(b). The readability of the first version is terrible and does not save on space so it would make no sense for it to be minified like that.
Assigning variables inside of conditional statements is bad practice.

Any difference in " 'value' == typeof X " VS " typeof X == 'value' "

Is there any difference (compiler/interpreter/juju wise, etc) between the two versions of checking the result of the typeof operator?
I am asking because I see the first version a lot of times, as if it followed a concept, while version two is way more readable and better describes my intention: primarily I am interested in the type of a variable and not a string being equal with something.
UPDATE:
while it's not part of the original question it worth noting that x == y is never a good practice when you are about to check equality. One should always use the === operator for that.
Update
There is no difference in terms of functionality but it seems that in JavaScript, you get an error in either way (which is good, thanks to JS):
Invalid left-hand side in assignment
So it seems to be just a habit of developers from other programming languages. For example in PHP if you did:
if ($var = 'foo')
PHP will silently assign foo as value to $var but with following:
if ('foo' = $var)
It will throw an error.
I am asking because I see the first version a lot of times
There is no difference in what they do. However first version will throw an error if you happen to write:
'value' = typeof X
Notice = instead of == or ===
This is generally good practice, people from other languages have habit of doing it that way in JavaScript also.
There will be no difference, as the equivalence operation will return the same thing, regardless of which way round it is.

Is it possible to use && and set a variable on same line?

I'm using:
MyTestFunction() && ExecuteMe();
for quick and easy conditional execution. I'd like to improve the code readability more in some places by creating:
Single line guard statments I.E:
MyTestFunction() && return;
//prevent execution of function early, but this isn't possible
Single line variable setters:
MyTestFunction() && myVar = 5;
(I realise I can do myVar = MyTestFunction() || 5; but that's not what I want)
Anyone see a nice way around this?
This works for me:
var num;
TestFunc() && (num = 5);
While I understand the programmers innate desire to do more things in less lines of code I think this violates some good programming principles about clarity in your code. Terse code saves space, but makes maintenance harder for the next programmer who looks at your code (and you should always assume there will be a "next programmer").
MyTestFunction() && (myVar = 5); // note the parens
// has the same effect as
if (MyTestFunction()) myVar = 5;
But I think the latter is much more readable and therefore easier to maintain.
I believe you are wanting to use a ternary statement
good thread here:
Operator precedence with Javascript Ternary operator

Comparison operation - Correct Syntax?

Coming from PHP I understand the difference in using == verses === in a comparison operation, but with JavaScript is it acceptable to use == or ===?
I wanted to validate my JavaScript code and found JSLint. While running the validation with JSLint I see these types of messages.
Some examples:
var show = $('input[name=female]:checked').val() == "true";
Problem at line 278 character 70: Expected '!==' and instead saw '!='.
and
var show = $('input[name=living]:checked').val() != "false";
Problem at line 283 character 38: Expected '!==' and instead saw '!='.
So My question is, Would using the current syntax of == or != be valid/correct or do I need to use === and !== ?
EDIT: Just to point out the code does work
It is correct in a way but JSLint expects strict comparison to prevent problems with type conversion.
It is good practice to always use strict comparison and "normal" comparison only where you really need/want it (because you want to make use of type conversion for some reason).
From JSLint's documentation:
== and !=
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.
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)
Always use the === and !==
operators.
Crockford and JSLint are somewhat dogmatic on this point, and I think over-prescriptive. Always using === rather than == is a reasonable rule of thumb for inexperienced JavaScript developers, but if you know the basic rules then there is no problem with using ==. In particular, if the two operands are guaranteed to be of the same type (such as in a typeof comparison like typeof foo == "undefined") then the two operators are specified to follow precisely the same steps.
There is also a reasonable point about habitually using === removing the need to think about which operator to use, but frankly I prefer to be forced to consider all the possible values of the two operands I'm comparing and find JSLint unnecessarily nannying.
The == syntax is valid but in some cases it can lead to rather nasty bugs in large projects. If you don't have a good reason to use == you should by default write JavaScript with === because it checks for type as you know.
It works either way, but you will save yourself pain in the future if you default to ===.
Depends on the situation.
=== is often preferred because you won't have any false-positives that you might not have considered (it might also be slightly quicker in some implementations because it compares to less potential values, although I haven't checked that, just a thought, and the speed difference would be negligible).
== is often more convenient to cover many/all cases (if I'm not mistaken, jQuery doesn't pass JSLint because in some places the code intentionally uses == to cover a multitude of cases rather than testing each one individually).
you can do just == and !=, I don't think there would be any problems with that.

JSLint The Javascript debugger: Should I debug these issues?

just started using JSLint on some code I bought some time ago. Its critsizing many lines of code... Whats your opinion on these lines? Should I rewrite them, and if so, how could these be fixed?
Problem at line 5 character 23: Use the array literal notation [ ]
var radios = new Array();
Problem at line 22: 'focustextareas' was used before it was defined
function focustextareas(){
Problem at line 125: Expected '===' and instead saw '=='
else if(elem.className=="optionsDivVisible") {elem.className = "optionsDivI...
Problem at line 133: Expected a conditional expression and instead saw an assignment
while(elem = document.getElementById("optionsDiv"+g))
Problem at line 136 character 13: Expected '{' and instead saw 'return'
return g;
Here are my opinions.
Using the literal [] notation is a good practice since it can avoid some confusing circumstances when using the constructor. Also, it's much shorter.
//var radios = new Array();
var radios = [];
The === uses a less complex algorithm and avoids some of the confusion that == can cause, so I'd use === whenever possible.
//else if(elem.className=="optionsDivVisible") {elem.className = "optionsDivI...
else if(elem.className==="optionsDivVisible") {elem.className = "optionsDivI...
I don't personally mind this one.
while(elem = document.getElementById("optionsDiv"+g))
I assume this one is the single statement for the previous while statement. I don't mind it, but at the same time, I don't think it is bad advice to say you should always place your statement in a Block {}.
return g;
You really should (if you haven't) read the docs for JSLint. The first sentence says: "JSLint will hurt your feelings."
JSLint was written by Doug Crockford and expresses his (very well founded) view of code quality and error prone coding. JSLint finds not only errors but as well "bad coding style". Crockford explains the reasoning behind JSLints suggestion in a very interesting video and in his book "JavaScript: The Good Parts".
JSLint is useful for pointing out common pitfalls in JavaScript and is especially useful for less experienced JavaScript developers. Some of it is sound, pretty much unarguably good advice. However, some of it represents only the views of its author, some of which are highly subjective. Here's my views on the examples you gave:
Problem at line 5 character 23: Use the array literal notation [ ]
Good advice. Array literals are shorter, safer and less ambiguous than using the Array constructor.
Problem at line 22: 'focustextareas' was used before it was defined
Good advice. JavaScript has both function declarations and function expressions, which behave differently in that functions created by function declarations are available in the whole scope in which they are defined whereas those created by function expressions do not. So the following works:
foo();
function foo() {}
... whereas the following does not:
foo(); // TypeError
var foo = function() {};
The problem here is that if you refactored a function declaration to a function expression, your code would stop working if that function was used before it was declared.
Problem at line 125: Expected '===' and instead saw '=='
else if(elem.className=="optionsDivVisible")
Questionable. No need to change. What this is trying to alert you to is that == does type coercion (the rules of which lead to some unintuitive results) whereas === does not. However, in this case both operands are guaranteed to be strings (so long as elem really is a DOM element), in which case === and == are specified to perform exactly the same steps and there is no advantage to using one over the other.
Problem at line 133: Expected a conditional expression and instead saw an assignment
while(elem = document.getElementById("optionsDiv"+g))
Good advice, but no need to change. I find this construction convenient and do use it, but it highlights a potential source of errors: if == or === was intended instead of = then this would not throw an error and lead to difficult-to-diagnose bugs.
Problem at line 136 character 13: Expected '{' and instead saw 'return'
return g;
Unsure. More code needed.
5: Use the array literal notation [ ] Many programmers prefer [] cause it's shorter.
22: 'focustextareas' was used before it was defined function may be used before its definition, but in some comlicated cases with closures, this would be a useful warning.
125: Expected '===' and instead saw '==' doesn't matter, class name is always a string.
133: Expected a conditional expression ... just a useful warning.
136: Expected '{' and instead saw 'return' hard to say. This message taken out from context look silly.

Categories

Resources