I want to understand why the parenthesis around
(o.method || true)()
var a = (o.method); a();
I think it has to do with ES5 11.1.6:
11.1.6 The Grouping Operator # Ⓣ
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
typeofmay 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.
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) 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.