在JavasScript ECMAScript 6中从string创build对象

我想使用ES6创build对象工厂,但旧式的语法不适用于新的。

我有下一个代码:

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'); 

我做错了什么?

不要把类名放在那个对象上。 把这些类放在那里,这样你就不必依赖它们是全局的,并且可以通过window访问(在浏览器中)。

顺便说一句,没有什么好的理由让这个工厂成为一个类,你可能只会实例化一次(singleton)。 只要把它作为一个对象:

 export class Column {} export class Sequence {} export class Checkbox {} export const columnFactory = { specColumn: { __default: Column, // <-- __sequence: Sequence, // <-- __checkbox: Checkbox // <-- }, create(name, ...args) { let cls = this.specColumn[name] || this.specColumn.__default; return new cls(...args); } }; 

有一个小而肮脏的方法来做到这一点:

 function createClassByName(name,...a) { var c = eval(name); return new c(...a); } 

你现在可以创build一个这样的类:

 let c = createClassByName( 'Person', x, y ); 

问题是这些类不是窗口对象的属性。 你可以有一个对象的属性“指向”你的类,而不是:

 class Column {} class Sequence {} class Checkbox {} let classes = { Column, Sequence, Checkbox } 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 classes[className](name); // this line no longer throw error } } let factory = new ColumnFactory(); let column = factory.create('userName'); export {ColumnFactory, Column, Sequence, Checkbox}; 

对于那些不使用ES6的人,想知道如何通过使用string来创build类,这是我所做的工作。

 "use strict"; class Person { constructor(x, y) { this.x = x; this.y = y; } } window.classes = {}; window.classes.Person = Person; document.body.innerText = JSON.stringify(new window.classes["Person"](1, 2)); 

正如你所看到的,最简单的方法就是将类添加到对象中。

这是小提琴: https : //jsfiddle.net/zxg7dsng/1/

这是一个使用这种方法的示例项目: https : //github.com/pdxjohnny/dist-rts-client-web