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.
November 21st, 2005 at 10:50 pm
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!
November 22nd, 2005 at 1:41 pm
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