On 2011-11-10, at 7:18 PM, Erick Lavoie wrote:

Running the following code in v8 I get:

0 var f = 0;
1
2 (function ()
3 {
4    try
5    {
6        throw 1;
7    } catch (f)
8    {
9        print(f);  // print 1
10       f = 2;
11       print(f);  // print 2
12   }
13   print(f);      // print 0
14 })();

However, replacing line 11 by

var f = 2;

will print 'undefined' at line 13 instead of '0'. Which means that
although catch introduces a lexical binding for f, a var statement with
the same name inside a catch block introduces a local variable spanning
the whole function. However, the assignation is still made on the
variable local to the catch statement!

I'll look at the standard to understand how this could be explained.

The explanation is simple. A catch introduces a new scope where the identifier of the thrown exception is a mutable binding. So, the assignments to f behave as you observed. However, the spec also states that the outer scope of the catch will be restored as to its original state after the execution of the catch:

"No matter how control leaves the Block the LexicalEnvironment is always restored to its former state." (ES5 spec, p97)

So, in the first case, 0 is printed because is bound to the global, which had the value 0 before the catch. In the second, f is bound to the local var, which was of course undefined before the catch.

Bruno