3

我有这样的东西...

define(['ClassA', 'ClassB', 'ClassC'], 
  function(ClassA, ClassB, ClassC) 
  {
    return {
      build: function(className) {
        var obj;
        switch(className)
        {
            case 'ClassA': obj = new ClassA(); break;
            case 'ClassB': obj = new ClassB(); break;
            case 'ClassC': obj = new ClassC(); break;
        }
        return obj;
    }
  }
}

这看起来不错,但有没有更好的方法来编写它?我尝试将 switch 替换为

return new arguments[className]();    // doesn't work

我能得到的最接近的是使用地图:

var classes = {
    ClassA: ClassA,
    ClassB: ClassB,
    ClassC: ClassC
}
return new classes[className]();

有没有更好的办法?

4

2 回答 2

3

你的对象在那里真的没有问题。
它快速、高效且易于遵循。
我唯一的建议是创建一个 var 来保存该值,或者更明确地测试是否className是一个合适的字符串,并且实际上在您的列表中:

任何一个:

var construct = classes[className];
if (construct) { return new construct(); }
else { /* handle the case where the class doesn't exist */ }

或者:

return classes[className] && (new classes[className]()) || null;

第二个检查 classes[className] 并且如果它存在应该返回一个新实例(JS 返回 AND 最右边的值)......
或者它将返回null.

也许null不是你想要的。
但关键是你应该准备好处理某人经过:"Bob"到你的工厂,尽管事实上没有Bob课程。

于 2012-10-19T01:04:05.443 回答
-1

使用功能模块作为工厂

define(function(require){
    var classes = {
        'ClassA' : require('ClassA'),
        'ClassB' : require('ClassB'),
        'ClassC' : require('ClassC')
    };

    return function(className){
        try {
            return new classes[className];
        } catch(error) {
            throw new Error('Unknown className Specified.');
        }
    }
});
于 2017-02-14T19:09:42.100 回答