[Greasemonkey] GM-TNG - several bugs fixed

Aaron Boodman zboogs at gmail.com
Wed Jul 27 10:26:03 EDT 2005


> function foo() {
> ...
> }
> 
> window.setTimeout(function(){ foo()}, 1000)

Or even 

window.setTimeout(foo, 1000), depending on what you expect |this| to
point to inside foo. If you do just pass a reference to foo to
setTimeout -- as I have here -- it will be executed with |this|
pointing to the global scope, which is in fact |window|. So that will
probably work most of the time.

The reason the two cases at the beginning of this thread are not the
same is that Greasemonkey does not run in the window's scope *on
purpose*. As GM matures it will probably get pulled even further and
further out of the window's scope.

So when you say:

function foo() { ... }

That does not go on window. Try it and see. It goes in a private
sandbox just for your user script. This is a good thing. It means that
your names don't accidentally squash content names or other script's
names.

You wreck this when you do:

window.foo = function() { ... }

The worst thing is that 999 times out of 1000 you don't need to do
this at all. The two most common reasons people do are:

* they are creating string-based event handlers: <div
onclick="window.doSomething()">
* they are creating string-based timeouts:
window.setTimeout("window.doSomething()")

But the string-based versions of both these capabilities are
incredibly lame. They run against the global scope, where your
function probably is not defined, and they have to be *parsed*. The
suggestion to use them at all is one of those awful things that has
been propagated across the internet as best practice by people who
don't know better.

Would JavaScript really not provide a mechanism to set a handler or
timeout function directly, without reparsing, compiling, and executing
a string of JavaScript?

Of course not. It's faster at execution time, easier to read, easier
to maintain, and cleaner to set the function references directly.

myDiv.onclick = doSomething;
window.setTimeout(doSomething, 1000);

So please, please let's try and kill this meme. The next time somebody
asks why their timeout is not working, tell them the function
reference solution. Not the janky window.foo solution.

Thanks. Sorry for the rant :-).

-- 
Aaron


More information about the Greasemonkey mailing list