Reputation: 9288
I encounter a very tricky case:
class C {
// class method are implicit in strict mode by default
static method() { return this === undefined; }
}
C.method(); // => false
(0,C.method)(); // => true
Why (0, C.method)
changes the binding of this
in the above case?
Upvotes: 1
Views: 148
Reputation: 287970
That's because C.method
returns a reference like
{ base: C, referencedName: "method", strict: strictFlag }
When you call it, JS obtains the function using GetValue with that reference, and provides the base of the reference (C
) as the this
value.
CallExpression : MemberExpression Arguments
1. Let ref be the result of evaluating MemberExpression. // <-- The reference
2. Let func be ? GetValue(ref). // <-- The function
4. If Type(ref) is Reference, then
a. If IsPropertyReference(ref) is true, then
i. Let thisValue be GetThisValue(ref). // <-- C
However, when you use the comma operator, you directly get the function, not the reference.
Expression : Expression , AssignmentExpression
1. Let lref be the result of evaluating Expression.
2. Perform ? GetValue(lref). // <-- 0
3. Let rref be the result of evaluating AssignmentExpression.
4. Return ? GetValue(rref). // <-- The function
Since there is no reference, JS can't know the base object, so when you call it provides undefined
as the this
value.
CallExpression : MemberExpression Arguments
1. Let ref be the result of evaluating MemberExpression. // <-- The function
2. Let func be ? GetValue(ref). // <-- The function
5. Else Type(ref) is not Reference,
1. Let thisValue be undefined. // <-- undefined
Upvotes: 4
Reputation: 33466
When you use the comma operator in JavaScript, both operands are evaluated, and then the right-most value is returned. The evaluated function value that comes out of the parentheses has no context of where it came from. This can be likened to assigning a value to a variable, where the right-hand side of the assignment operator =
is evaluated before the value is assigned:
(0, C.method)();
// ^^^^^^^^ evaluates here
var func = C.method;
// ^^^^^^^^ evaluates here
func();
Once a function is put into a variable, it loses all context of what object it came from (unless bind
is used). This context is important to determining the value of this
. When a function is called without being the member of an object, it defaults to the global object, or undefined
if the function is in strict mode. (MDN)
Upvotes: 3