On Feb 15, 2012, at 3:55 AM, Andy Wingo wrote:

> Hello again ecmascriptians,
> 
> There has been some discussion about treating function declarations as
> "var" declarations.  While I understand the concerns about
> compatibility, I think it will be surprising to programmers.

Not really,  the intent is that function declarations are lexically scoped to 
the closest inclosing block (or function body), just like let. The primary 
difference between let and function is that the initialization of a function 
binding occurs at the top of the enclosing block

Treating function like var has only been discussed in a couple of contexts.

At the global level function may need to bind like var rather than let for 
browser legacy compatibility reasons and in support of multiple top-level 
script blocks.

The other var related issue concerning function scoping also relates to legacy 
compatibility.  ES5 and earlier does not allow for  function declarations in 
blocks. However, all browser JS implementations do allow such declarations but 
they don't agree upon a common semantics.  Some treat such function 
declarations like var declarations in terms of hoisting.  FF does something 
that is somewhat similar to let, but not quite the same thing.  In general, use 
of such function declarations are not interoperable among browsers, but there 
are some simple usage patterns that will produce the same results in all 
browsers.

At the last TC39 meeting it was hypothesized that the block nested function 
declaration patterns that are actually used inoperably on the web would 
continue to work if interpreted as lexical (let-like) declarations.  On that 
basis, we decided that we would go forward with let-like scoping of block 
nested functions for all ES6 code. However, we will also experiment with early 
implementations to ensure that this does not "break the web".  If it does, we 
will have to revisit the issue and probably only use let-like scoping for 
functions within strict mode.

> 
> For example:
> 
>  function f(x) {
>    bar(); // ???
>    for (let y of x) {
>      function bar() { ... y ... }
>      bar(); // OK
>    }
>    bar(); // ??? 
>  }
> 

both var references outside of the for-let block result to their bindings in 
the scope that surrounds the declaration of f.  If that is the global scope, 
they probably throw as unresolved references.

> Here I think it's pretty natural to expect that the FunctionBody of
> `bar' has access to lexically scoped binding for `y'.  But outside the
> block, the function bound to `bar' doesn't have any meaning.

outer scope reference

> 
> I only see two consistent answers here:
> 
>  function foo(){}  ==  let foo = function(){}
> 
> or
> 
>  funciton foo(){}  ==  var foo = function(){}
> 
> Hoisting the function definition doesn't make sense with block scope.

All declarations within a block are "hoisted" to the top of the block but can 
only be validly referenced after they have been initialized.  The span between 
the top of the block and the point of initialization is called the "temporal 
dead zone".  Function declarations are initialized at the top of the block.  
Let and const declaration are initialized when evaluated in statement list 
order.

Allen
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to