Why comma operator changes `this` in function call

Given:

foo.bar()

Inside bar, this will be foo.

(There are exceptions, such as when bar is defined with an arrow function, but they don't apply in this case).

Given:

const bar = foo.bar;
bar();

Now the function has been called without the context of foo so this is now the default object (which is window in a browser).

The expression: (1, foo.bar) evaluates as the right-hand side. This is the function.

Just as if you had copied it to a variable, this disconnects the function from the object before you call it, so you get the same effect.

There's no assignment because you haven't involved a variable, but you are calling the result of an expression and not the object method directly.


To support @Quentin's answer, the comma operator indeed returns the last operand as a function without context (hence window) rather than the one from the object's blueprint.

Only on calling apply/call over the function with the object, it can gain the context back.

(1, a.fn).call(a); // "object"
(1, a.fn).apply(a); // "object"