0

Parenthesis have higher precedence than equality.

So from my understanding, the higher precedence is evaluated first.

Lets now assume I compare a which is not defined:

if (a == 1) { .. // throws an exception because a is not defined

Actual case:

if (typeof a !== 'undefined' && (a == 1)) {
  console.log(1)
} else {  
  console.log(2)
}

should be evaluated in this order:

  1. (typeof a !== 'undefined' && (a == 1))
  2. (a == 1)
  3. typeof a
  4. result from (3) !== 'undefined'
  5. "result from (4)" && "result from (2)"

But this would usually throw an exception if a is not defined but it doesn't.

Why is the left side of the equation evaluated first even though it has the lower precedence?

EDIT: I adapted the example from '||' to && just because || would always throw.

Andi Giga
  • 3,744
  • 9
  • 38
  • 68
  • 1
    Parens don't add "weight", they group operations together that normally wouldn't be: `a || b && c || d` vs `(a || b) && (c || d)` – Cerbrus Jul 05 '19 at 06:43
  • Where are you getting the values of precedence from? If statements literally go from left to right, comparing the results (regardless of the type). – Reinstate Monica Cellio Jul 05 '19 at 06:46
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence – Andi Giga Jul 05 '19 at 06:48
  • In grade school arithmetic classes, they conflate the ideas of operator precedence and order of evaluation -- in something like `3 + 4 - (5 + 6)`, they tell you to compute `5 + 6` and then `3 + 4 - 11` -- which is fine because order of evaluation doesn't matter in arithmetic as long as you respect operator precedence. But in programming, where order of evaluation often *does* matter (because expressions can have side effects), you need to keep these concepts separate; respecting operator precedence isn't enough. – ruakh Jul 05 '19 at 06:48
  • Okay - that would only affect calculations prior to the `if` statement running left to right. `if (2 + 3 * 4 == 3 * 2 + 1)` would correctly calculate `if (14 == 7)` but then it's just an `if` statement. Left to right - always. – Reinstate Monica Cellio Jul 05 '19 at 06:51
  • @ruakh probably country dependant. I was taught that you'd need to eliminate the brackets to use the contents within, true, but it's not necessarily the *first* thing you do. So you can sum the first parts `3+4 = 7` and *in parallel* sum `5 + 6 = 11`. So, the next step in the evaluation is `7 - 11`. You just don't do something like a `3 + 4 - 5 + 6` all in one go but keep the parts of the equation separate. – VLAZ Jul 05 '19 at 07:55

1 Answers1

1

|| is evaluated left-to-right:

5 Logical OR left-to-right … || …

So the inner expression that gets evaluated first is typeof a, as part of typeof a !== 'undefined'.

If the right-hand side of the || contains more expressions nested in parentheses, regardless of their operator precedence, they will only be evaluated after the left-hand side of the || has been evaluated.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • Isn't `&&` also evaluated left to right? Isn't every `if` statement? – Reinstate Monica Cellio Jul 05 '19 at 06:41
  • Yep, *most* things are evaluated left to right, like you can see on the MDN link (though it's *per expression*, rather than *per statement*) – CertainPerformance Jul 05 '19 at 06:42
  • Yes, but shouldn't be the inner parenthesis with precedence `20 ` be evaluated over the `5`? – Andi Giga Jul 05 '19 at 06:43
  • @AndiGiga No, the outer expression is the `||`, so the left-hand side of the `||` will be evaluated before anything on the right, no matter the precedence of any of the operators that happen to be nested on the right – CertainPerformance Jul 05 '19 at 06:45
  • But wouldn't than be `if (someVar && (someConditional == someBool))` equal to `if (someVar && someConditional == someBool)`. – Andi Giga Jul 05 '19 at 06:47
  • `typeof a !== 'undefined' && (a == 1)` can be seen as `(typeof a !== 'undefined' && (a == 1))`. The outer expression is still `(foo && bar)`. `foo`gets evaluated first. – Cerbrus Jul 05 '19 at 06:47
  • I came to this question, from the answer here: https://stackoverflow.com/questions/56882749/decaffeinated-double-brackets – Andi Giga Jul 05 '19 at 06:47
  • @AndiGiga Yes, those two expressions are equivalent, because `==` has higher priority than `&&` already – CertainPerformance Jul 05 '19 at 06:50
  • The answer you linked has been updated, @AndiGiga. It's now correct. – Cerbrus Jul 05 '19 at 07:35
  • @AndiGiga I had already put a comment on that answer since yesterday showing it was incorrect. Maybe I should have been more explicit in calling this out but I ran out of characters for the comment... – VLAZ Jul 05 '19 at 07:51