The trouble with with

I’ve long been told that the with keyword in JavaScript is bad news, and long believed it. Today, I had a reminder of why that was.

I’m looking at a HTML form, that I want to parse programmatically rather than doing a straight submit. The parsing code that i’m modifying looks roughly like this:

var status=null;
with (document.myForm){
for (var i=0;i<elements.length;i++){
if (elements[i].name=="status"){
status=elements[i].value;
}else{
//do something else here...
}
}
}

I introduced the variable status, because I wanted to single it out for special treatment, and set it’s value to the value of the corresponding form element.

When I run it, the fifth line kept throwing an error, and I ran round the houses checking that elements[i] has a value property and so on, before I twigged to the cause.

The variable status is defined outside the with{} block. Within the with block, however, every variable name will first be resolved as a member of the object being with-ed (there must be a neater way of saying this, but you know what I mean). And document.myForm.status will resolve to the form element called ’status’, which it is an error to assign a value to.

with is generally advised against for being slow to execute, as far as I’m aware. As a side effect, it can also generate extremely confusing code.

2 Responses to “The trouble with with

  1. Simon Warrick Says:

    Hands up! It was me. I have an excuse, and it’s a poor one. Without the “with” the amount of typing I was going to have to do was much greater. As I wrote it, I cringed. It’s one of those weird pieces of code that even a year on(?) I still remember writing and hating as I felt sure there was a simpler better way to do it, but as usual it was urgent that it be done… I have a feeling that it may be the only time it is used throughout the whole 10000+ lines of code, and you found it… Thanks Dave!

  2. dave Says:

    Thanks for owning up, Simon. I’ll have to fix it now, rather than just griping about it on my blog :-)

    For the benefit of everybody not in the Historic Futures office today, we decided that the best solution that doesn’t use ‘with’ is simply to define a local variable to do what you want.

    var status=null;
    var els=document.myForm.elements;
    for (var i=0;i