[Greasemonkey] With Statement

Edward Lee edilee at gmail.com
Mon Apr 25 12:20:48 EDT 2005


Pulled out of the other discussion.. (This is possibly informative for
those playing around with setTimeout/Interval.)

On 4/22/05, Aaron Boodman <zboogs at gmail.com> wrote:
> And don't use the with statement ;-). Blech.

While this example is slightly contrived.. it could happen! ;)
Basically it starts out with Hello World in separate id's, and the
script should do a delayed alert Hello followed by World and also
changing the message to Bye Bye!!, but a problem will appear for
someone not paying attention to variable details/changes.

The problem comes up because the tmp variable is reused later and by
the time the timeout is called, there is a new value for tmp.

(function() {
document.body.innerHTML = '<a id="a">Hello</a> <a id="b">World</a>'

var tmp = document.getElementById('a');
setTimeout(function() {
  alert(tmp.innerHTML);
  tmp.innerHTML = 'Bye';
}, 250);

var tmp = document.getElementById('b');
setTimeout(function() {
  alert(tmp.innerHTML);
  tmp.innerHTML = 'Bye!!';
}, 500);
}) ();

However, this implementation works fine with "with" because it keeps
track of its variable

(function() {
document.body.innerHTML = '<a id="a">Hello</a> <a id="b">World</a>'

with (document.getElementById('a')) {
  setTimeout(function() {
    alert(innerHTML);
    innerHTML = 'Bye';
  }, 250);
}

with (document.getElementById('b')) {
  setTimeout(function() {
    alert(innerHTML);
    innerHTML = 'Bye!!';
  }, 500);
}
}) ();

Like Aaron pointed out in the other post, using "with" with object
member creation is a bad idea because strange things can happen. But I
don't see anything too too bad using "with" for objects already
provided such as DOM Nodes which should always have certain members
such as innerHTML, style and other fun stuff.

But then, all this could be gotten around without "with" with the
example I gave in the Patterns topic of
setTimeout( (function(tmp) { return function() { /*original function
using tmp*/ }; }) (tmp), time);

Or.. just don't reuse variables ;)

-- 
Ed


More information about the Greasemonkey mailing list