Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(function eval () {}) throws a syntax error if function body is in strict mode?

Why does this code throw an error?

// global non-strict code
(function eval () { 'use strict'; });

Live demo: http://jsfiddle.net/SE3eX/1/

So, what we have here is a named function expression. I'd like to explicitly point out that this function expression appears in non-strict code. As you can see, its function body is strict code.

The strict mode rules are here: http://ecma-international.org/ecma-262/5.1/#sec-C

The relevant bullet is this one (it's the last one on the list):

It is a SyntaxError to use within strict mode code the identifiers eval or arguments as the Identifier of a FunctionDeclaration or FunctionExpression or as a formal parameter name (13.1). Attempting to dynamically define such a strict mode function using the Function constructor (15.3.2) will throw a SyntaxError exception.

Notice how this rule only applies if the function declaration/expression itself appears in strict code, which it does not in my example above.

But it still throws an error? Why?

like image 731
Šime Vidas Avatar asked Sep 24 '12 16:09

Šime Vidas


People also ask

What does eval function do in JavaScript?

JavaScript eval() The eval() method evaluates or executes an argument. If the argument is an expression, eval() evaluates the expression. If the argument is one or more JavaScript statements, eval() executes the statements.

What is function form of use strict?

The "use strict" Directive It is not a statement, but a literal expression, ignored by earlier versions of JavaScript. The purpose of "use strict" is to indicate that the code should be executed in "strict mode". With strict mode, you can not, for example, use undeclared variables.

What is the statement to enable strict mode in JavaScript?

The statement “use strict”; instructs the browser to use the Strict mode, which is a reduced and safer feature set of JavaScript. Benefits of using 'use strict': Strict mode makes several changes to normal JavaScript semantics.

Which choice is a result of invoking strict mode in JavaScript?

By changing errors to throw errors, strict mode removes certain JavaScript silent errors. Strict mode repairs mistakes that make it difficult for JavaScript engines to perform optimizations. (It can sometimes execute faster than identical code that's not strict mode.) Strict mode forbids certain JavaScript syntax.


1 Answers

§13.1 outlines what ought to happen in cases such as yours:

  • It is a SyntaxError if any Identifier value occurs more than once within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression.
  • It is a SyntaxError if the Identifier "eval" or the Identifier "arguments" occurs within a - FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression.
  • It is a SyntaxError if the Identifier "eval" or the Identifier "arguments" occurs as the Identifier of a strict mode FunctionDeclaration or FunctionExpression.

Emphasis mine. Your strict-mode function's identifier is eval, thus, it's a SyntaxError. Game over.


To see why the above is a "strict mode function expression," look at the semantic definitions in §13 (Function Definition):

The production
FunctionExpression : function Identifieropt( FormalParameterListopt) { FunctionBody } is evaluated as follows:

  1. Return the result of creating a new Function object as specified in 13.2 with parameters specified by FormalParameterListopt and body specified by FunctionBody. Pass in the LexicalEnvironment of the running execution context as the Scope. Pass in true as the Strict flag if the FunctionExpression is contained in strict code or if its FunctionBody is strict code.

Emphasis mine. The above shows how a function expression (or declaration) becomes strict. What it says (in plain English) is that a FunctionExpression is strict in two scenarios:

  1. It's called from a use strict context.
  2. Its function body begins with use strict.

Your confusion arises from thinking that only the function body is strict, when in fact, the entire function expression is strict. Your logic, while intuitive, is not how JS works.


If you're wondering why ECMAscript works this way, it's pretty simple. Suppose we have this:

// look ma, I'm not strict
(function eval() {
     "use strict";
     // evil stuff
     eval(); // this is a perfectly legal recursive call, and oh look...
             // ... I implicitly redefined eval() in a strict block
     // evil stuff
})();

Thankfully, the above code will throw because the entire function expression is flagged as strict.

like image 179
David Titarenco Avatar answered Sep 29 '22 22:09

David Titarenco