Ser*_*pov 10 javascript ecmascript-6 babeljs
我想使用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');
Run Code Online (Sandbox Code Playgroud)
我做错了什么?
不要在该对象上放置类名.把类本身放在那里,这样你就不必依赖它们是全局的并且可以访问(在浏览器中)window
.
顺便说一句,没有充分的理由让这个工厂成为一个类,你可能只会实例化一次(单例).把它变成一个对象:
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);
}
};
Run Code Online (Sandbox Code Playgroud)
问题是这些类不是窗口对象的属性。您可以拥有一个具有“指向”您的类的属性的对象:
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};
Run Code Online (Sandbox Code Playgroud)
有一种小而脏的方法:
function createClassByName(name,...a) {
var c = eval(name);
return new c(...a);
}
Run Code Online (Sandbox Code Playgroud)
您现在可以创建一个类:
let c = createClassByName( 'Person', x, y );
Run Code Online (Sandbox Code Playgroud)