3

I've been doing JS development for a long time now, and for years I thought I could short circuit a conditional statement using the logical AND. In fact, I do this ALL THE TIME in my React components with conditional rendering. But it turns out it doesn't work the way I would expect all the time. The question is, why?

Here is an example for Node 8.15.0:

> a = 0.0
0
> a && console.log(a)
0
> if(a) console.log(a)
undefined
> !!a && console.log(a)
false

Specifically, why does a && console.log(a) not work the same as if (a) console.log(a)

DaKaZ
  • 925
  • 1
  • 7
  • 18
  • 3
    What behavior are you expecting? All of those look correct to me. If the problem is the `undefined`, many JS repls print `undefined` when you give it a statement that doesn't return a value (like an if statement) – y2bd Jan 17 '19 at 23:00
  • 3
    It works exactly as I expect it. What did you expect? – Michael Jan 17 '19 at 23:01
  • Value 0 is not equal True. `a && console.log(a)` is one-liner and it means: `if (a==true) { console.log(a) }` ... check this answer https://stackoverflow.com/a/5515349/4415165 – Chamov Jan 17 '19 at 23:02
  • 2
    `falsey && val` evaluates to `falsey`. `truthy && val` evaluates to `val`. What do you expect instead? And why? –  Jan 17 '19 at 23:02
  • Specifically why does `a && console.log(a)` not evaluate the same as `if (a) console.log(a)` – DaKaZ Jan 17 '19 at 23:04
  • Because one is an expression, the other a statement. `var result = a && console.log(a)` makes perfect sense. `var result = if (a) console.log(a)` not so much. So why would you expect the two to exhibit the same behavior? –  Jan 17 '19 at 23:05

3 Answers3

5

if(a) ... is a statement. a && ... is an expression.

This behaviour is specific to a console. If a line evaluates to an expression, the result outputted, otherwise it's considered that a line was evaluated to undefined.

a && ... is a short-circuit. This means that if a is falsy, the expression evaluates to a. If a is truthy, the expression is evaluated to ....

This doesn't affect the way both are used in real application instead of a console. If the result of the evaluation isn't used, both if and short-circuit evalution act the same way, i.e. evaluate ... only if a condition is truthy.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • Oh yes! The answer is that if it evaluates to falsey, it returns the left side of the expression. THANK YOU!! – DaKaZ Jan 17 '19 at 23:07
  • 1
    @DaKaZ It doesn't always return the left side, it returns *the first falsey value*. For example, `true && "Hello World" && 0 && false` would be `0`. – Tyler Roper Jan 17 '19 at 23:10
1

!! operator convert variable to boolean. In your case a equal to 0 so it will convert it to false, and because of this you see false as output for !!a && console.log(a)

0

The first expression outputs 1 line to the console, which is what the statement evaluates to:

a && console.log(a)
0

The expression clearly evaluates to the value of a. That's because this short circuit evaluation can be considered equivalent to the following conditional ternary:

a ? console.log(a) : a

The second expression evaluates to undefined because it is not an actual expression but a block construct. With braces this time:

if (a) { console.log(a) }
undefined

The third expression is quite similar to the first one, except that this time not the value of a is returned but the value of the sub-expression !!a, or false:

!!a && console.log(a)
false

Note If a would be a truthy value both the first and third statements would evaluate to undefined, the return value of console.log.

JJWesterkamp
  • 7,559
  • 1
  • 22
  • 28