Javascript ‘with’ clause

I encountered a neat little feature in javascript recently.

Javascript has things that look like global variables. They’re not. What they *actually* are is fields of the global object. The following syntax lets you write a bunch of code that uses a different global object:

with(foo)
{
// do Stuff
}

Has foo as the global object inside the braces.

Well, almost. There’s a caveat.

Try the following in Rhino or Spidermonkey:

foo = { bar : 2 };

with (foo)
{
baz = 3;
}

print(foo.baz);

It will print “undefined”.

But if you do

print(baz)

It will print 3.

Huh? What’s going on?

This is how javascript scope works. The assignment “foo = bar” will not find the identifier ‘foo’ bound, so will fall outwards into enclosing scopes until it finds a scope which does bind it, stopping at the top level scope (and corresponding global object) if it doesn’t find any.

It’s kindof annoying, but it does make sense. Further it’s more or less how it has to work given the combination of Javascript’s soft objects and lexical scoping.

With this caveat borne in mind, the ‘with’ method is quite cool. I shall try and find an excuse to use it in future. :-) (I encountered it via Chickenfoot, where it seems to be useful for loading other pages in the background and applying chickenfoot methods to them).

Update: Apparently this is deprecated and considered bad practice, as it’s difficult to optimise and leads to some non-intuitive issues with scoping. Oh well.

This entry was posted in programming and tagged on by .