使用unsafeWindow插入带有Greasemonkey的多个javascript函数时出现问题

使用unsafeWindow插入带有Greasemonkey的多个javascript函数时出现问题,javascript,greasemonkey,Javascript,Greasemonkey,问题在于,这些函数似乎无法相互看到 例如: unsafeWindow.helloworld = function() { alert('Hello world!'); helloworld2();//fails with error saying it does not exist } unsafeWindow.helloworld2 = function() { alert('Hello world!2'); helloworld();//fails

问题在于,这些函数似乎无法相互看到

例如:

unsafeWindow.helloworld = function() {

    alert('Hello world!');

    helloworld2();//fails with error saying it does not exist
}

unsafeWindow.helloworld2 = function() {

    alert('Hello world!2');

    helloworld();//fails with error saying it does not exist
}

insert("helloworld();"); //appends a script element to the body

这两个函数都可以使用insert或firebug控制台调用,但它们在内部互不了解?这里有什么问题?

如果您格式化代码,会有很大帮助:

> unsafeWindow.helloworld = function() {
> 
>     alert('Hello world!');
> 
>     // fails with error saying it does not exist
>     helloworld2(); 
> }
> 
> unsafeWindow.helloworld2 = function() {
> 
>     alert('Hello world!2');
> 
>     //fails with error saying it does not exist
>     helloworld();
> 
> }
在无限递归函数中,helloworld调用helloworld2,helloworld2调用helloworld,因此无穷大

但无论如何,您正在设置
unsafeWindow
的属性:

unsafeWindow.helloworld = function() {
但随后尝试使用范围链上解析的非限定标识符调用它:

[... later, in helloword2 ...]

      helloworld();
因此,标识符
helloworld
在调用
unsafeWindow.helloworld2
时创建的执行/变量对象的范围链上解析

因此
helloworld
被设置为
unsafeWindow
属性。调用函数时,标识符
helloworld2
将使用函数的作用域链进行解析

在浏览器中,窗口/全局对象位于作用域链上,因此可以在那里找到变量名(即,如果在作用域链中没有更早地找到变量,则变量可能解析为全局对象的属性),但我怀疑当调用
unsafeWindow.helloworld
时,其作用域链以文档的全局对象结束,不
unsafeWindow
。否则,对文档中函数的调用在其作用域链上也会有
unsafeWindow
,这在我看来是不对的


或者我可能完全错了。:-)

存在多个问题

  • 由于函数是在
    unsafeWindow
    范围中定义的,因此必须在Greasemonkey脚本中以这种方式调用它们。
    像这样:


  • insert()
    从哪里来?!要调用这些函数,请使用:

    // WARNING this will launch an infinite loop!!
    unsafeWindow.helloworld2 ();
    

  • 别这样!以这种方式定义函数的唯一原因是重写/覆盖目标页上已存在的函数。在少数情况下,当您确实希望覆盖网站的JavaScript时,最好的方法取决于细节

    您可以使用大量的
    unsafeWindow
    转义(如图所示),但最好的方法通常只是删除页面的函数:
    unsafeWindow.badFunc=function(){}

    并在GM脚本范围内替换/添加更改的功能


  • 但是对于目前发布的问题,你不需要做任何事情。根据所显示的内容,脚本应该是:

    helloworld = function () {
    
        alert ('Hello world!');
        helloworld2 ();
    }
    
    helloworld2 = function () {
    
        alert ('Hello world!2');
        helloworld ();
    }
    
    // WARNING this will launch an infinite loop!!
    helloworld2 ();
    

  • 也许我误解了不安全窗户的使用。我只是尝试将JavaScript添加到现有网页中,然后让它在GM后可执行。例如:在GM中:unsafeWindow.newfunction=function(){…}在网页中:你说我必须使用unsafeWindow.newfunction?但是我认为在GM完成运行后,这是不可用的。insert()就像我说的那样,只是创建一个脚本元素并将其附加到网页正文中(即它只是从网页内调用代码的一种方式)(我尝试使用此函数插入我现在尝试使用unsafeWindow插入的函数,但我认为我遇到了相同的作用域问题).好的,将unsafeWindow添加到我的代码中似乎已经修复了它。非常感谢您的帮助。这是一个绕口令,但它仍然帮助解决了我的问题。对于任何不理解这一点的人,这里是我的解释(我确信它在某些方面存在严重缺陷):函数是“编译的”当它们被创建时,即使函数将嵌入到网页中,您仍然需要在创建它时使用unsafeWindow作用域调用它(以便GM可以找到它)。`unsafeWindow.helloworld2=function(){alert(“HW”);unsafeWindow.helloworld();}`好的,我还是搞不懂这个格式,在我再次发布之前,我会研究它。好的,我还是搞不懂这个格式,在我再次发布之前,我会进一步研究它。help完全错了,我不知道为什么``不起作用,为什么任何网站会使用这个令人困惑的格式系统。
    helloworld = function () {
    
        alert ('Hello world!');
        helloworld2 ();
    }
    
    helloworld2 = function () {
    
        alert ('Hello world!2');
        helloworld ();
    }
    
    // WARNING this will launch an infinite loop!!
    helloworld2 ();