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?
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:
Declaring a closure in a loop is a common task where this can lead to errors:
Because the for loop does not introduce a new scope, the same
num
- with a value of2
- will be shared by all three functions.A new scope:
let
andwith
With the introduction of the
let
statement in ES6, it becomes easy to introduce a new scope when necessary to avoid these problems:Or even:
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
: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.I have been using the with statement as a simple form of scoped import. Let's say you have a markup builder of some sort. Rather than writing:
You could instead write:
For this use case, I am not doing any assignment, so I don't have the ambiguity problem associated with that.
I think the obvious use is as a shortcut. If you're e.g. initializing an object you simply save typing a lot of "ObjectName." Kind of like lisp's "with-slots" which lets you write
which is the same as writing
It's more obvious why this is a shortcut then when your language allows "Objectname.foo" but still.
I think the object literal use is interesting, like a drop-in replacement for using a closure
or the with statement equivilent of a closure
I think the real risk is accidently minipulating variables that are not part of the with statement, which is why I like the object literal being passed into with, you can see exactly what it will be in the added context in the code.
Here's a good use for
with
: adding new elements to an Object Literal, based on values stored in that Object. Here's an example that I just used today:I had a set of possible tiles (with openings facing top, bottom, left, or right) that could be used, and I wanted a quick way of adding a list of tiles which would be always placed and locked at the start of the game. I didn't want to keep typing
types.tbr
for each type in the list, so I just usedwith
.Hardly seems worth it since you can do the following: