[Greasemonkey] Re: Can anybody explain to me the strange namespace
rule?
Nikolas Coukouma
atrus at atrus.org
Tue Jun 6 15:34:25 EDT 2006
Linan Wang wrote:
> I noticed that in greasemonkey scripts, to add a link in a page call a self
> defined function, have to 'hook' the function into the unsafeWindow. For
> example:
>
> var alink=document.createElement('a');
> a.innerHTML='A link';
> a.href='javascript:self_defined_function()';
>
> unsafeWindow.self_defined_function=function(){
> another_function();
> };
>
> function another_function(){}
This works fine, and doesn't touch unsafeWindow:
var a=document.createElement('a');
a.innerHTML='A link';
a.addEventListener('click', function() {
another_function();
}, false, false);
document.body.appendChild(a);
function another_function() {
alert("hi");
}
Although the following works just fine in my test:
var a=document.createElement('a');
a.innerHTML='A link';
a.href='javascript:self_defined_function()';
document.body.appendChild(a);
unsafeWindow.self_defined_function=function(){
another_function();
};
function another_function(){alert("hi");}
> It is understandable, but in the 'self_defined_function', if i want to call
> another function defined in userscript, that function should NOT be hooked
> into unsafe. Why? Can anybody explain to me?
If I understand correctly, you're asking why you can write
function another_function(){alert("hi");}
instead of
unsafeWindow.another_function = function(){alert("hi");}
The reason is that functions in JavaScripts are closures. That means
they carry their scope with them. The following probably doesn't look
too weird if you're used to global variables:
count = 0;
function foo() {
count++
alert(count);
}
// 1
foo();
// 2
foo();
But this probably seems strange:
function foo_gen(label) {
count = 0;
function foo() {
count++
alert(count + "(" + label + ")");
}
return foo;
}
foo_gen returns a function. Each time foo_gen is called a new namespace
is created, so each function returned has it's own count and label:
foo_a = foo_gen("a");
// 1 (a)
foo_a();
foo_b = foo_gen("b");
// 1 (b)
foo_b();
// 2 (a)
foo_a();
// 3 (a)
foo_a();
// 2 (b)
foo_b();
I hope that helps more than it confuses.
Cheers,
-Nikolas
More information about the Greasemonkey
mailing list