在JavasScript ECMAScript 6中从字符串创建对象

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)

我做错了什么?

Ber*_*rgi 9

不要在该对象上放置类名.把类本身放在那里,这样你就不必依赖它们是全局的并且可以访问(在浏览器中)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)


Ami*_*mit 6

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

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)


eco*_*747 6

有一种小而脏的方法:

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)

  • 我也+1。我知道每个人都谴责评估,但是只要您完全控制可能的值,它就是最简单,最灵活的解决方案。 (2认同)