在requirejs中按名称调用构造函数/函数

时间:2015-04-16 17:18:53

标签: javascript requirejs

我有这样的代码

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

其中

className

是某些"类"的名称。我已创建并在我的html中的属性中指定。 我所要做的就是确保我在className中加载了名称的构造函数/函数,并且它有效。

我已经开始将所有内容都收录到 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

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

您似乎不知道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'](...);
    ...
});

或者甚至更好,不要在全球空间泄漏任何东西并做:

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来合并模块,则必须显式列出您以上述方式加载的模块,因为{ {1}}无法遵循计算的依赖关系。