从阅读示例来看,这似乎应该很容易。这是我的代码:

rhkTest = {
  onPageLoad: function(event) {
    var doc = event.originalTarget;
    var wnd = doc.defaultView;
    var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
      .getService(Components.interfaces.mozIJSSubScriptLoader);
    loader.loadSubScript("chrome://rhkoshi-extension/content/testfoo.js", wnd);
    alert('typeof(wnd) = ' + typeof(wnd));
    alert('typeof(wnd.window.rhk_test1) = ' + typeof(wnd.window.rhk_test1));
    alert('typeof(wnd.window.rhk_test2) = ' + typeof(wnd.window.rhk_test2));
    alert('typeof(wnd.window.rhk_test3) = ' + typeof(wnd.window.rhk_test3));
    alert('typeof(wnd.rhk_test1) = ' + typeof(wnd.rhk_test1));
    alert('typeof(wnd.rhk_test2) = ' + typeof(wnd.rhk_test2));
    alert('typeof(wnd.rhk_test3) = ' + typeof(wnd.rhk_test3));
    alert('typeof(rhk_test1) = ' + typeof(rhk_test1));
    alert('typeof(rhk_test2) = ' + typeof(rhk_test2));
    alert('typeof(rhk_test3) = ' + typeof(rhk_test3));
    alert('typeof(this.rhk_test1) = ' + typeof(this.rhk_test1));
    alert('typeof(this.rhk_test2) = ' + typeof(this.rhk_test2));
    alert('typeof(this.rhk_test3) = ' + typeof(this.rhk_test3));
    alert('typeof(window.rhk_test1) = ' + typeof(window.rhk_test1));
    alert('typeof(window.rhk_test2) = ' + typeof(window.rhk_test2));
    alert('typeof(window.rhk_test3) = ' + typeof(window.rhk_test3));
  },
  onLoad: function(event) {
    var appcontent = document.getElementById("appcontent");
    if (appcontent) {
      appcontent.addEventListener("DOMContentLoaded", rhkTest.onPageLoad, true);
    }
  },
};

window.addEventListener("load", function(e) { rhkTest.onLoad(e); }, false);


其中testfoo.js包含:

window.rhk_test1 = 'testval1';
rhk_test2 = 'testval2';
var rhk_test3 = 'testval3';

window.alert('Running testfoo.js');


我收到警报“正在运行testfoo.js”,因此该文件已找到并执行。我还收到一条警报,指出wnd是一个“对象”(正如预期的那样-在其他地方已初始化)。但是,所有其他警报对于各种typeof()调用都显示“未定义”。当然,我并不希望所有这些都具有价值,但我希望其中至少有一个能显示一些价值。

我的价值观发生了什么?他们不应该属于WND的财产吗?

我正在Windows 7上运行Firefox 19.0(如果有的话)。

最佳答案

实际上有点复杂,取决于wnd是什么。您可以使用常规对象作为下标的范围:

var myScope = this;
var subscriptScope = {};
loader.loadSubScript("testfoo.js", subscriptScope);


但是,范围并没有被完全隔离。以下是testfoo.js中代码的一些示例:

var foo = "bar;      // Creates subscriptScope.foo
xyz = 1;             // Creates myScope.xyz
function dummy() {}  // Creates subscriptScope.dummy
var outer = myScope; // Assigns a value from outer scope


因此,尽管下标的变量和函数是在其作用域中定义的,但它仍可以访问加载该脚本的脚本的作用域-未声明的变量仍将在外部作用域中创建,并且将在外部作用域中搜索无法在下标范围内解决。

如果您真的想隔离下标,则应该使用“适当的”全局对象,例如窗口对象或沙箱:

var myScope = this;
var subscriptScope = new Components.utils.Sandbox("about:blank");
loader.loadSubScript("testfoo.js", subscriptScope);


现在testfoo.js将不再能够访问外部作用域:

var foo = "bar;      // Creates subscriptScope.foo
xyz = 1;             // Creates subscriptScope.xyz
function dummy() {}  // Creates subscriptScope.dummy
var outer = myScope; // Exception: myScope is not defined


请注意,window变量没有什么特别的-如果您希望下标具有该变量,则必须在范围对象中对其进行定义,例如:

subscriptScope.window = subscriptScope;


范围对象本身可以在下标的顶层作为this访问。

07-27 13:29