我想使用ES6创建对象工厂,但旧样式的语法不适用于新的。
我有下一个代码:
export class Column {}
export class Sequence {}
export class Checkbox {}
export class ColumnFactory {
constructor() {
this.specColumn = {
__default: 'Column',
__sequence: 'Sequence',
__checkbox: 'Checkbox'
};
}
create(name) {
let className = this.specColumn[name] ? this.specColumn[name] : this.specColumn['__default'];
return new window[className](name); // this line throw error
}
}
let factory = new ColumnFactory();
let column = factory.create('userName');
我做错了什么?
8条答案
按热度按时间vc6uscn91#
不要把类名放在那个对象上,把类本身放在那里,这样你就不必依赖于它们是全局的,并且可以通过
window
访问(在浏览器中)。顺便说一句,没有很好的理由把这个工厂变成一个类,你可能只会示例化它一次(单例),只要把它变成一个对象:
qnzebej02#
有一个小而肮脏的方法来做到这一点:
现在您可以创建如下的类:
aiazj4mn3#
问题是类不是窗口对象的属性,你可以让一个对象的属性“指向”你的类:
vc9ivgsu4#
对于那些没有使用ES6并且想知道如何通过使用字符串来创建类的人,下面是我为使其工作所做的工作。
正如您所看到的,最简单的方法是将类添加到对象中。
小提琴在这里:https://jsfiddle.net/zxg7dsng/1/
下面是使用此方法的示例项目:https://github.com/pdxjohnny/dist-rts-client-web
93ze6v8z5#
我更喜欢这种方法:
allThemClasses.js
script.js
tag5nh1u6#
我知道这是一篇老文章,但最近我也遇到了同样的问题,即如何动态地示例化一个类
我使用的是webpack,因此按照文档说明,可以使用***import()***函数动态加载模块
js/类/我的类.js
js/应用程序js
注意: 这个方法是异步的,我不能确定它的性能代价,但是它在我的简单程序上工作得很好(值得一试^^)
***附言 *:**说实话,我是Es6的新手(几天),我更像是一个C++ / PHP / Java开发人员。
我希望这对任何遇到这个问题的人都有帮助,这不是一个坏的做法。
6g8kf2rb7#
还有类似的问题,包括这个被关闭的SO question,它们在JavaScript中寻找代理类或工厂函数;也称为动态类。这个答案是一个现代的解决方案,以防你降落在这个答案寻找任何这些东西。
到2022年,我认为有一个更优雅的解决方案可以在浏览器中使用,我创建了一个名为
Classes
的类,它在窗口上自注册属性Class
(大写C);下面的代码示例。现在,您可以让希望能够动态引用的类全局注册它们自己:
然后,在代码的后面,您所需要的只是希望获得其原始引用的类的名称:
或者,更简单的是,直接示例化它:
你可以看到latest code on my gist,在所有其他脚本之前添加这个脚本,你的所有类都可以注册到它。
qacovj5a8#
这是一个古老的问题,但我们可以找到三个非常聪明和有用的主要方法:
1.丑陋的人
我们可以使用
eval
来示例化我们的类,如下所示:然而,
eval
有一个很大的警告,如果我们不清理,不添加一些安全层,那么我们将有一个很大的安全整体,可以暴露。2.善
如果我们知道将要使用的类名,那么我们可以创建一个如下所示的查找表:
3.模式
最后,我们可以创建一个
Factory
类,它将安全地处理允许的类,如果可以加载它,则抛出一个错误。我推荐The Good方法。它是干净和安全的。而且,它应该比使用
global
或window
对象更好:class
定义不会像其他顶级变量声明那样自动放在global
对象上(JavaScript试图避免在以前的设计错误上添加更多垃圾)。global
对象,因为我们使用本地classMap
对象来查找所需的class
。