在普通的js中,可以迭代窗口对象 -
<html><head><script>
function one(){
}
function two(){
for (var i in window) {
if (i=='one') {
alert(i);//.......................shows 'one'
}
}
}
two();
</script></head></html>
但是在greasemonkey中,'window'不包含函数,甚至是你在GM脚本中定义的函数:
// ==UserScript==
// @name Page 3
// @namespace http://xxxxxxxxxxxxxxxx
// @include http://xxxxxxxxx.net/3.html
// ==/UserScript==
//
function one(){
}
function two(){
for (var i in window) {
if (i=='one') {
alert(i);//.........shows nothing, only iterates native window props
}
}
}
two();
是的,我想迭代我自己的函数,而不是unsafeWindow中的函数。请注意以下工作,我不想这样做:
window.one=function one(){
}
function two(){
for (var i in window) {
if (i=='one') {
alert(i);//...........ta-da! 'one'
}
}
}
two();
那么这个全球空间的名称是什么,我如何迭代它以及这个异常的意图和最佳实践是什么?谢谢。
更新:'this'也无法访问这些功能 -
// ==UserScript==
// @name Page 3
// @namespace http://xxxxxxx.net
// @include http://xxxx.com/*
// ==/UserScript==
function do_fixes(){
var s='';
for (var i in this) {
if (i=='do_fixes') {
alert('yes');
}
}
if (window!=this) {
alert('window!=this');
}
}
do_fixes();
alert('this script ran!');
答案 0 :(得分:1)
全局对象应该可以在全局范围和自由函数中以this
访问。从Greasemonkey Environment上的Greasemonkey手册页面
除非用户脚本头中存在@unwrap元数据命令,否则整个脚本将包含在匿名函数中,以保证脚本的标识符不会与Mozilla JavaScript沙箱中的标识符冲突。此函数包装器将所有函数定义和
var
变量声明(例如var i = 5;
)捕获到函数的本地作用域中。但是,没有var
的声明将最终出现在脚本的this
对象上,该对象在Greasemonkey中是全局对象,与普通浏览器对象模型相反,window
对象填充此函数
皱纹是你需要unwrap将函数的脚本添加到脚本全局(注意全局变量可以通过this
访问而不需要解包)。请注意,建议@unwrap
仅用于调试,因为如果变量和函数具有相同的名称,它们将与沙箱变量和函数冲突。
另一种方法是创建自己的对象来代替全局对象:
var global = {};
global.one = function () {...};
global.two = function (target) {
for (p in global) {
if (p == target) {
GM_log("found " +target);
}
}
};
two('one');
虽然您可以在脚本全局中明确地添加函数作为方法,但这会给您带来两个世界中最糟糕的:与沙箱属性的冲突并且它不是自动的。