Are there legitimate uses for JavaScript's "with" statement?

javascript, language-features, with-statement

Solution

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 ES6, it becomes easy to introduce a new scope when necessary to avoid these problems:

// variables introduced in this statement 
// are scoped to each iteration of the loop
for (let i=0; i<3; ++i)
{
   setTimeout(function() { alert(i); }, 10);
}

Or even:

for (var i=0; i<3; ++i)
{
   // variables introduced in this statement 
   // are scoped to the block containing it.
   let num = i;
   setTimeout(function() { alert(num); }, 10);
}

Until ES6 is universally available, this use remains limited to the newest browsers and developers willing to use transpilers. 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, 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). This behavior is actually quite similar to a `let` block syntax introduced in earlier versions of Mozilla browsers, but not widely adopted elsewhere.

Problem

Alan Storm's comments in response to my answer regarding the `with` statement got me thinking. I've seldom found a reason to use this particular language feature, and had never given much thought to how it might cause trouble. Now, I'm curious as to how I might make effective use of `with`, while avoiding its pitfalls. Where have you found the `with` statement useful?

Original source

Related problems