在 requirejs 中按名称调用 constructor/function

Call constructor/function by name, within requirejs

我有这样的代码

var e = new window[className](...);

其中

className

是我创建的一些 "class" 的名称,并在我的 html 的属性中指定。 我所要做的就是确保我已经在 className 中加载了名称的 constructor/function 并且它有效。

我已经开始将我所有的东西都放入 require 中,这不出所料地停止了工作。 我有一个我需要的文件 Eric.js,其中包含

define('Eric',function(){
var Eric = function (ED) {
...
};
// etc

return Eric;
});

但是

require(['wtt/Eric']);
className='Eric';
var e = new window[className](...);

产生

TypeError: window[className] is not a constructor

requirejs 的典型用法是:

require(['wtt/Eric'], function(Eric) {
    var e = new Eric(...);
});

你可以这样使用require吗?

P.S。顺便说一句,你应该避免在你的代码中使用全局变量,并在 Eric 模块定义中添加小修复:

define('Eric', function() {
    var Eric = function (ED) { // <- here comes the "var" keyword
        // ...
    };
    // etc

    return Eric;
});

你可以阅读更多让我们在这里说:http://www.w3.org/wiki/JavaScript_best_practices#Avoid_globals

您似乎没有意识到 RequireJS 操作异步。让我们看看您的代码:

require(['wtt/Eric']);
className='Eric';
var e = new window[className](...);

第一行 (require...) 将导致 RequireJS 启动 加载您的模块。您实际上并不知道何时 加载模块。事实上,鉴于 JavaScript 的工作方式,您可以保证在 var e = new window[className](...); 执行时,您的模块将 不会 被加载并且该行将失败。所以你必须构建你的代码,这样失败的行保证 运行 模块加载之后。您可以通过将回调传递给 require:

来完成此操作
require(['wtt/Eric'], function () {
    var e = new window['Eric'](...);
    ...
});

或者更好的是,不要在全局 space 中泄漏任何内容并执行:

require(['wtt/Eric'], function (Eric) {
    var e = new Eric();
    ...
});

关于您在其他答案中留下的评论,请注意可以计算在 运行 时间加载什么模块:

var mod = document.getElementById("myid").attributes.foo.value;
require(['wtt/' + mod], function (Constructor) {
    var e = new Constructor();
});

如果您曾经使用 r.js 组合您的模块,则必须 明确地 列出您以我上面刚刚显示的方式加载的模块,因为r.js 无法遵循计算的依赖项。