That's a really cool trick/abuse of syntax that goes back to the confusing `this` in javascript.
calling a method or function directly (when in the global scope) will set `this` to the global object. But calling a method or bound function could have a different `this`, and calling a function directly in another context can have a different `this`.
the `(0, funcName)` syntax works by evaluating each item in the parens, but returns the last item. (don't ask me why this is in the syntax, I genuinely don't know and have never seen it used beyond this as far as I know)
So that syntax is abused to basically (simplified here) reassign the funcName to strip out the `this` that is bound to it and reassign it to the global context.
It then evals that `this`, and returns it! Meaning it will always get the global `this`, or `globalThis`!
In C, the commas are also used in macro definitions where you need multiple statements to be output by the macro, but can’t use semicolons because the macro might expand in a context where only one statement is expected. In both the OP and this one,it comes off as clever but tricky.
so the comma operator doesn't do anything special other than return the last value - so why not just call eval directly?
If somebody rebound eval to redefine the 'this' inside - e.g., eval = (function(){myThis = ... ; return function(a){eval.apply(mythis, [a]);};})();
then calling eval with (0, eval)('this') will still not have rebinded the 'this' inside eval right? So why not just directly call eval('this')? Or am i missing the point?
It's getting to the limit of my knowledge here, so please don't take this as fact, however:
I believe it is because of a weird distinction between "direct" and "indirect" calls in javascript. The spec says that an indirect call is guaranteed to execute in the global context, but a direct call will execute in whatever context it's in.
The `(0, eval)` makes it an indirect call by evaluating an expression that returns the function.
I'm not quite sure about the details of why indirect calls are treated that way though...
This is correct, for details this is specified as point 15.1.2.1 in ES spec:
> (...) any invocation of eval that is not a direct call uses the global environment as its variable environment rather than the caller’s variable environment.
I believe it is because of a weird distinction between "direct" and "indirect" calls in javascript. The spec says that an indirect call is guaranteed to execute in the global context, but a direct call will execute in whatever context it's in.
The `(0, eval)` makes it an indirect call by evaluating an expression that returns the function.
This is really timely. I just ran into an issue this weekend where I tried to generalize a function call like this (unaware of the direct vs. indirect semantics), and TypeScript yelled at me about it. Looks like it was trying to evaluate it in the global context, so the error makes sense now.
calling a method or function directly (when in the global scope) will set `this` to the global object. But calling a method or bound function could have a different `this`, and calling a function directly in another context can have a different `this`.
the `(0, funcName)` syntax works by evaluating each item in the parens, but returns the last item. (don't ask me why this is in the syntax, I genuinely don't know and have never seen it used beyond this as far as I know)
So that syntax is abused to basically (simplified here) reassign the funcName to strip out the `this` that is bound to it and reassign it to the global context.
It then evals that `this`, and returns it! Meaning it will always get the global `this`, or `globalThis`!
It would be similar to doing this: