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