TL; DR
The second case (0, eval)('var a = 1;'); not really a direct challenge.
You can see this more widely in:
(function(){ "use strict" var x = eval; x("var y = 10");
The question can be found in:
If the eval code is strict code then (me: fix context)
But strict eval code is defined as:
Eval code is strict eval code if it starts with the Prologue directive containing the Strict directive, or if the eval call is a direct call.
Since the call is not direct, the eval code is not strict eval code, and execution is performed in a global scope.
First of all, the big question.
"Eval Code" is more general than direct or indirect calling eval .
Check exact specification for eval function
15.1.2.1 eval (x)
When the eval function is called with one argument x, the following steps are performed:
If Type (x) is not a string, return x.
Let prog be the ECMAScript code that is the result of parsing x as a program. If the parsing fails, throw a SyntaxError exception (but see also section 16).
Let evalCtx be the result of creating a new execution context (10.4.2) for the eval code project.
Let the result be the result of evaluating the program.
Close the execCert execution context evalCtx, restoring the previous execution context ....
So, let's examine what 10.4.2 tells us, you quoted this: in a specific case, consider the first sentence:
If the call context is missing or if the eval code is not evaluated by a direct call (15.1.2.1.1) for the eval function, then ... Initialize the execution context, as if it were a global execution context
So what is a direct call?
A direct call to the eval function is an expression expressed as a call expression that satisfies the following two conditions:
The link, which is the result of evaluating MemberExpression in CallExpression, has an environment record as its base value, and its reference name is "eval".
The result of calling the abstract GetValue operation with this reference as an argument is the standard built-in function defined in 15.1.2.1.
So what is MemberExpression in both cases?
In eval('var a = 1;'); indeed, the result of its evaluation has the reference name eval and a call to GetValue on it returns an inline function.
In (0, eval)('var a = 1;'); The result of evaluating a member expression does not have the reference name eval . (However, it allows the built-in GetValue function).
What are the link names?
Section 8.7 in the specification tells us:
A link is a permitted name binding. The reference consists of three components, a base value referenced by a name and a Boolean-valued strictly basic flag. The base value is either undefined, object, logical, string, number or environment record (10.2.1). A base value of undefined indicates that the link cannot be resolved by binding. The specified name is a string.
This requires us to look for GetReferencedName :
GetReferencedName (V). Returns the link component of the link name V.
So, although the expression (0,eval) === eval true, when evaluating a function, it is actually an indirect call due to naming.
Can I suggest a Function constructor instead :)?