Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Function statements in strict mode #118

Closed
r-e-d opened this issue Aug 28, 2014 · 11 comments
Closed

Function statements in strict mode #118

r-e-d opened this issue Aug 28, 2014 · 11 comments

Comments

@r-e-d
Copy link
Contributor

r-e-d commented Aug 28, 2014

In strict mode, function statements are only allowed at the top level of a script or function (source). Currently acorn accepts code that does not follow this rule.

For example, this code should throw a SyntaxError :

"use strict";
if (true)
  function bar() { }
@getify
Copy link

getify commented Aug 28, 2014

I don't think that's accurate. In fact, I believe as of ES6, this is officially allowed.

Trying it in Chrome:

function foo(a) {
   "use strict";
   if (a) {
      function bar() { console.log(a); }
      bar();
   }

   bar();
}

function bar() { console.log("oops"); }

foo();           // "oops"
foo("hello");    // "hello"   "oops"

I think the difference is that if (a) function ... is not allowed, but if (a) { function ... } is.

@RReverser
Copy link
Member

@getify Agree, but weird that MDN page and ES5 standard mention that this should be prohibited (while browsers don't).

@getify
Copy link

getify commented Aug 28, 2014

Let's ask @allenwb or @rwaldron for clarification. :)

@r-e-d
Copy link
Contributor Author

r-e-d commented Aug 28, 2014

@getify, if i copy/paste your foo function in the console in Chrome (or Firefox), I get "SyntaxError: In strict mode code, functions can only be declared at top level or immediately within another function".

@getify
Copy link

getify commented Aug 28, 2014

@r-e-d

Could be that I'm running Chrome canary with ES6 stuff turned on? Shrugs.

chrome screenshot

@allenwb
Copy link

allenwb commented Aug 28, 2014

First ES5 and ES6 are different.
In ES5 strict mode, all non-top level functions declarations (by informal agreement among browser implementators, not by spec. ) should be illegal.

In ES6, function declarations are legal (regardless of mode) in blocks. In strict mode, function declarations are still illegal as single statements such as if (true) function foo() {};. In theory, the same applies to non-strict mode, but for browsers specifically, Annex B rules apply: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-block-level-function-declarations-web-legacy-compatibility-semantics and http://people.mozilla.org/~jorendorff/es6-draft.html#sec-functiondeclarations-in-ifstatement-statement-clauses.

There is no particular reason to assume, at this point in time, that Chrome, FF, MDN, or anything else has yet to get this all correct.

@getify
Copy link

getify commented Aug 28, 2014

Thanks for the great clarifications, @allenwb. I suspected exactly that, but you're the authority. :)

From your perspective, do you think a parser should disallow things that the spec allows (or allow things the spec disallows) simply because browsers/annex-b cause divergence?

My take is that a parser should follow the spec strictly, and not concern itself with browser variances.

@allenwb
Copy link

allenwb commented Aug 28, 2014

If you're building a browser (or processing web content scripts some other way) you need to implement Annex B in order to be compatible with existing web content. But, generally, stuff in Annex B is stuff a JS programmer should ever intentionally code. That's why it's in Annex B rather than the main body of the spec.

If you are building something other than a web browser and don't need to worry about compatibility will all existing web content, then you should just ignore Annex B and fully conform to the main body of the spec.

@getify
Copy link

getify commented Aug 28, 2014

Building off what @allenwb said, I guess I would clarify my perspective as: a JS parser (not attached to a browser, mind-you) should take the more lenient (less errors) of either two positions if there's a divergence between the spec and browsers/annexB. If browsers throw an error but standard spec JS doesn't, the JS parser shouldn't. If the spec throws an error, but the browsers don't, the JS parser shouldn't. Only if both agree on throwing an error should the JS parser throw it. Just my 2 cents.

@RReverser
Copy link
Member

Agree with @getify here. I think parser is more generic and can be used by any kind of tools, so should choose to throw less errors whenever it's allowed by spec.

@marijnh
Copy link
Member

marijnh commented Sep 24, 2014

Agreed. Let's close this, and reconsider when it becomes clear what browsers will do in ES6-mode.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants