Uniform block scoping

Andreas Rossberg rossberg at google.com
Tue Jul 15 23:13:38 PDT 2014

ES6 will have block scoping. However, it turns out that there are at
least two different forms of blocks in the language:

- normal block statements
- block-like bodies hardwired into other constructs (try/catch bodies,
function bodies)

In the current draft spec, these come with different rules regarding
shadowing. For example:

  let x; { let x }  // fine, shadowing

  for (let x...) { let x }  // fine, shadowing

  try {} catch(x) { let x }  // redeclaration error

  function(x) { let x }  // redeclaration error

  (function x() { let x })  // fine, shadowing

I think this subtle discrepancy is both unfortunate and unnecessary
[1]. Moreover, with ES7 do expressions, I would like it to hold that

  (...) => {...}    ≡    (...) => do {...}

so the former shouldn't impose extra restrictions. Therefor, I suggest
we implement the uniform principle that every braced statement list
behaves like a proper block (i.e., allows lexical declarations to
shadow outer variables, regardless of how those are bound).

In terms of spec, this simply amounts to dropping several bullet
points imposing syntactic restrictions about LexicallyDeclaredNames
[2] -- i.e., simplification :). (Note: The legacy rule that legal ES5
function declarations are var-like, not lexical, would of course be

[1] issue: https://bugs.ecmascript.org/show_bug.cgi?id=3005
[2] in current Sections 13.14.1, 14.1.2, 14.2.1, 14.3.1, 14.4.1


PS: With respect to try/catch/finally, I also wonder why we cannot
simply relax the syntax and drop the hardwired block syntax. Then the
block-scoping rules would follow naturally.

More information about the es-discuss mailing list