Another use occurred to me today, so i searched the web excitedly and found an existing mention of it: Defining Variables inside Block Scope.
Background
JavaScript, in spite of its superficial resemblance to C and C++, does not scope variables to the block they are defined in:
var name = "Joe";
if ( true )
{
var name = "Jack";
}
// name now contains "Jack"
Declaring a closure in a loop is a common task where this can lead to errors:
for (var i=0; i<3; ++i)
{
var num = i;
setTimeout(function() { alert(num); }, 10);
}
Because the for loop does not introduce a new scope, the same num
- with a value of 2
- will be shared by all three functions.
A new scope: let
and with
With the introduction of the let
statement in JavaScript 1.7, it becomes easy to introduce a new scope when necessary to avoid these problems:
for (var i=0; i<3; ++i)
{
// variables introduced in this statement
// are scoped to the block following it.
let (num = i)
{
setTimeout(function() { alert(num); }, 10);
}
}
But until other browsers implement it, this will remain limited to Mozilla-targeted code. However, we can easily simulate this behavior using with
:
for (var i=0; i<3; ++i)
{
// object members introduced in this statement
// are scoped to the block following it.
with ({num: i})
{
setTimeout(function() { alert(num); }, 10);
}
}
The loop now works as intended, creating three separate variables with values from 0 to 2. Note that variables declared within the block are not scoped to it - this is identical to the behavior of let
, but unlike the behavior of blocks in C++ (in C, variables must be declared at the start of a block, so in a way it is similar).