0

While compressing my code, I found compilers converting if & elses to raw logic like:

if (a) b(); to a && b();

After some comprehension it made sense, however I never knew you could use &&s and ||s outside of if()s.

What I wanted to know was, are they exactly the same - is if simply an alias for the && structure, and the same for || to else? Does a browser compile if (a) b(); to a && b(); without me even knowing?

Also, how bad of a practice is it to use the a && b(); notation.

I'm guessing it would be condemned for its lack of readability, but it's really short...

  • they are the same, since in the notation: a && b(), b() is only run if a is truthy. Which is the same as saying if a is true, then do b(). i don't know about how the compiler treats these – Cruiser Sep 04 '16 at 20:06
  • && and || are operators. Like all operators they both produce a result that can be tested (a condition). All `if` does is test a condition and if it evaluates to true it will execute a statement. In the trivial case (where there is only one condition and no else statement), `if (a) b()` and `a && b()` are equivalent. – Tibrogargan Sep 04 '16 at 20:08

2 Answers2

2

No. if (condition) stmt1 else stmt2 is closer to condition ? stmt1 : stmt2. You can see the difference when you consider the completion value.

var b = true;
var n = 1;

&& and if look the same when the condition is true:

alert(eval('if (b) { n }'));  // 1
alert(eval('b && n'));  // 1

but they differ when the condition is false.

alert(eval('if (!b) { n }'));  // undefined
alert(eval('!b && n'));  // false

a && b evaluates to a when it is truthy or b otherwise, but if (a) b else c is much closer to a ? b : c in its completion behavior because if (a) b is shorthand for if (a) b else {}.

var a = true;
var b = 1;
var c = 2;

alert(eval('a ? b : c'));  // 1
alert(eval('!a ? b : c'));  // 2

alert(eval('if (a) b; else c'));  // 1
alert(eval('if (!a) b; else c'));  // 2

Also, how bad of a practice is it to use the a && b(); notation.

Let your JS minifier make it shorter.

Is there a good JavaScript minifier?

Community
  • 1
  • 1
Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
1

Any expression in Javascript is also a statement.

Expressions are things like:

1 + 3
a - b
4 + f(5)

Each of these expressions evaluate to a result, you don't have to capture it though. Just like you can throw a function's return value away by simply not assigning it anywhere with an '=', you can throw any expression's return value away. The following is valid:

function a() {
    8 + 5;
    "hello";
    a == 3;
}

Admittedly this function isn't very useful, but it demonstrates how expressions' outputs can be thrown away.

Now, onto the example you provided... The && operator is a logical AND. It takes two parameters (either side of it), and evaluates to either true or false. Typically you'd use it like this:

var result = f(4) && f(5);

This operator also has another aspect to its behaviour, though; it does 'short-circuit evaluation'. What does this mean? Consider what an AND actually does; it only returns true if both parameter are true.

If the first parameter is false, there's no point in checking the second one, because you already know that they aren't both true, and you know that your result will be false. 'Short-circuit evaluation' is when the runtime doesn't bother evaluating the second argument if the first argument already gives it everything it needs.

In the case of &&, if the first parameter is false, it will not bother evaluating the second parameter. If the second parameter is the return value of a function, like a && b(3), b(3) WILL NOT be called. If a is true, on the other hand, b(3) will need to be called to figure out if a && b(3) is true.

So thanks to short-circuit evaluation, the logical AND actually behaves like an if-then, only evaluating the second parameter if the first one is true.

The opposite is true for the || (OR) operator, where the second parameter is only evaluated if the first is false (because true OR anything is always true).

Going back to the start of this answer now, where we talked about expressions, we see that the a && b() expression can just be used standalone. We don't need to capture the result, we just want to use short-circuit evaluation to control whether or not b() is called. The eventual result, true or false, is thrown away.

More information on short-circuit evaluation

Lee Marshall
  • 302
  • 1
  • 3
  • So: `var a = b && c` assigns a boolean to a; however, `var a = b || c` assigns a the first truthy value, or undefined. The lack of symmetry leads me to believe somethings wrong. –  Sep 16 '16 at 07:45