In JavaScript and Java, the equals operator (==
or ===
) has a higher precedence than the OR operator (||
). Yet both languages (JS, Jav
Or am I confusing matters?
You are. I think it's much simpler to think about precedence as grouping than ordering. It affects the order of evaluation, but only because it changes the grouping.
I don't know about Javascript for sure, but in Java operands are always evaluated in left-to-right order. The fact that ==
has higher precedence than ||
just means that
true || foo == getValue()
is evaluated as
true || (foo == getValue())
rather than
(true || foo) == getValue()
If you just think about precedence in that way, and then consider that evaluation is always left-to-right (so the left operand of ||
is always evaluated before the right operand, for example) then everything's simple - and getValue()
is never evaluated due to short-circuiting.
To remove short-circuiting from the equation, consider this example instead:
A + B * C
... where A
, B
and C
could just be variables, or they could be other expressions such as method calls. In Java, this is guaranteed to be evaluated as:
A
(and remember it for later)B
C
B
and C
A
with the result of the multiplicationNote how even though *
has higher precedence than +
, A
is still evaluated before either B
or C
. If you want to think of precedence in terms of ordering, note how the multiplication still happens before the addition - but it still fulfills the left-to-right evaluation order too.
There is no operator precedence in this case. What you are questioning is like in f(callback)
statement the callback
function being evaluated even before f
. This can not happen.
On the other hand, in JS the ||
is one of the few places where you can watch laziness at show. The ==
operand (think as if it is an infix function like in fully functional languages) takes two arguments and the one on the left gets evaluated first. If it resolves to true
the second argument doesn't even get evaluated.
According to the language specification, https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.24
At run time, the left-hand operand expression is evaluated first; if the result has type Boolean, it is subjected to unboxing conversion (§5.1.8).
If the resulting value is true, the value of the conditional-or expression is true and the right-hand operand expression is not evaluated.
So if you have a || b==c
, it is not interpreted as (a || b) == c
, because ||
has lower precedence, as you found in the tutorial. Instead, it is interpreted as a || (b==c)
. Now since a
is the left side of ||
, it is evaluated first.