I think it has to do with ES5 11.1.6:
11.1.6 The Grouping Operator # Ⓣ
The production PrimaryExpression : ( Expression )
is evaluated as follows:
- Return the result of evaluating
Expression
. This may be of type Reference.
NOTE This algorithm does not apply GetValue to the result of evaluating Expression. The principal motivation for this is so that operators such as delete
and typeof
may be applied to parenthesised expressions.
Let's see how function invocation is done in JS:
The key point is that o.method
is a Reference (as defined by the spec):
A Reference is a resolved name binding. A Reference consists of three components, the base value, the referenced name and the Boolean valued strict reference flag.
So, o.method
is not a Function YET; it is basically [[o, "method", false]]
. When invoked with an argument list, o.method()
, the reference value is taken by GetValue, then the method invocation proceeds (as described in 11.2.3).
When you do (o.method)()
, (o.method)
is still a Reference - GetValue has still not been applied to it (per the quoted 11.1.6). So nothing changes.
When you do (o.method || true)()
, ||
will apply GetValue to the left side (per 11.11) and produce a function value - not a Reference any more. Thus, it cannot be evaluated as a method invocation, since the information about the base and referenced name (that was present in Reference) is lost.