我在使用javascript代码模块进行firefox插件时遇到了这种奇怪的行为。我不确定这是一个错误还是一个糟糕的设计进行相互导入。
所以我们假设有3个模块a,b和c。
a.js
var EXPORTED_SYMBOLS = ["a"];
Components.utils.import("resource://mymodule/c.js");
Components.utils.import("resource://mymodule/b.js");
var a = {
init: function() {
dump("A init\n");
b.init();
}
};
b.js
var EXPORTED_SYMBOLS = ["b"];
Components.utils.import("resource://mymodule/c.js");
var b = {
init : function() {
try {
dump("B init\n");
dump(c.foo() + "\n");
} catch (e) {
dump("Error C init : " + e.message + "\n");
}
}
};
c.js
var EXPORTED_SYMBOLS = ["c"];
Components.utils.import("resource://mymodule/b.js");
var c = {
foo : function() {
return "C Foo";
},
};
a.init()在外部调用。现在使用上面的代码,我从b中找到了未定义的'c'。
A init
B init
Error C init : c is undefined
经过一些故障排除后,我意识到要纠正这个问题,
在我的实际代码中,b和c表示一些与UI相关的东西,它们具有相互依赖性。我可以完全摆脱相互导入的模块,并为其中一个注册回调函数。但我想知道导致这种行为的原因。据我所知the documentation没有任何严格的模块导入指南。由于模块的缓存,我也知道one module when imported multiple times will be shared。但不知何故无法解释这一点。我在这里做错了什么?
答案 0 :(得分:1)
我有一个关于发生了什么的理论,虽然我没有尝试在调试器中运行代码来确保:
c
在c.js范围内仍未定义(因为c
尚未继续运行;它仍在等待第2行的c.js
调用返回), import
被注入b.js范围。因此b.js永远不会收到c = undefined
的有效绑定,而c
在尝试访问b.init()
时会抛出异常。
如果这个理论是正确的,我认为你可以通过将b.js和c.js中的导入调用移到这些文件的底部来修复错误。