tags:

views:

114

answers:

3

What are the pros and cons of function-level scope specifically in Javascript compared to block-level scope in languages like Java?

I would like to see examples of function-level scope usage that would be harder or impossible to implement using block-level scope.

+3  A: 
T.J. Crowder
You mean if implemented with **block** level scope.
Peter Ajtai
@Peter: Crikey, now there's a slip of the fingers... Thanks!
T.J. Crowder
A: 

There is nothing you cannot do - it is not hard to simulate function level scope with block level scope or vice versa.

Conditional function declarations would be more awkward though:

if (console && console.log) {
    function debug(msg) { console.log(msg); }
} else {
    function debug(msg) { alert(msg); }
}
debug('foo'); // does not work with block scope
Tgr
That actually was never standardized, it will work *only* in Mozilla implementations, because they define a Function Statement, thing that doesn't exist on the ECMAScript specification. Other implementations will simply take the last `FunctionDeclaration` although the code *should* cause a `SyntaxError` because there is no grammar production that can accept FD's inside blocks.
CMS
@CMS: Indeed. Tgr: You should use function expressions to assign functions conditionally. See http://kangax.github.com/nfe/#expr-vs-decl
Marcel Korpel
@CMS: *"...because there is no grammar production that can accept FD's inside blocks."* Wow, that part I did not know. I knew that the `FunctionDeclaration` would be processed regardless of where it was inside the function (e.g., not conditionally), but I didn't realize that the grammar didn't support it. As you indicate, bad idea regardless, of course. As Marcel said, use a function expression (and as Marcel's excellent link to kangax's article points out, unless you want [IE/JScript problems](http://blog.niftysnippets.org/2010/09/double-take.html), an anonymous one).
T.J. Crowder
@T.J., yes there are some *unofficial syntactic extensions* supported by a large number of implementations, another example, the literals: `08` or `09`, they are *not* valid `NumericLiteral`, because a `DecimalIntegerLiteral` cannot start with `0` (unless of course the `0` value itself), and they don't match with the `OctalIntegerLiteral` grammar: `0 OctalDigit`, because obviously, an octal digit can be only one of `0`,`1`,`2`,`3`,`4`,`5`,`6` and `7`. Those literals should cause a `SyntaxError` but turns out that in all implementations the leading zero is simply ignored, `08 == 8`, `09 == 9`.
CMS
+2  A: 

I would like to see examples of function-level scope usage that would be harder or impossible to implement using block-level scope.

Maybe it will sound obvious, but you can implement recursion in function-level scope, which can be often useful, for example:

var x = 5; // global scope

(function (y) { // y - locally scoped variable on each execution
  y && arguments.callee(--y); // recursion!
  console.log(y);
})(x);

That is mostly impossible to implement with block-level scope.

In the above example the function will initially be executed passing the value of the outer x variable to it, before the function is invoked a new execution context is setup, that initializes a new lexical scope, where the y formal parameter is bound to it.

After that, the function expression is executed again -if y is not 0- initializing on each execution a completely new lexical scope.

CMS