如何从描述性对象动态生成类?

时间:2019-01-13 01:11:26

标签: javascript ecmascript-6

我正在尝试完成一个函数,该函数接收一个对象作为参数并返回基于接收到的描述性对象生成的类(或构造函数)。是否有任何不使用'eval'的解决方法?

// this is the function to create class.
function createClass (option) {
    // TODO how to generate...
    // return classGenerated
}

// then, i can do this to create a 'Node' class.
createClass({
    name: "Node",
    data: {
        x: 0,
        y: 0
    },
    methods: {
        translate (dx, dy) {
            this.x += dx;
            this.y += dy;
        }
    }
})

// then i can create a instance by doing this below.
const node = new Node();

我已经通过“评估”功能完成了一个版本。我想知道是否还有其他更好的方法可以做到这一点。谢谢您的帮助。

2 个答案:

答案 0 :(得分:1)

考虑使用类的对象而不是独立的动态变量名称,而是使用类名称(例如Node)进行索引,以便您可以执行类似const node = new createdClasses.Node()的操作:

const createdClasses = {};
function createClass ({ name, data, methods }) {
  class theClass {
    constructor() {
      Object.assign(this, data);
    }
  }
  Object.assign(theClass.prototype, methods);
  createdClasses[name] = theClass;
}
createClass({
  name: "Node",
  data: {
      x: 0,
      y: 0
  },
  methods: {
      translate (dx, dy) {
          this.x += dx;
          this.y += dy;
      }
  }
})

const node = new createdClasses.Node();
node.translate(5, 5);
console.log(node.x);

答案 1 :(得分:0)

您可以利用Java语言Clojures,但必须有稍微不同的行为:您不能全局定义一个类(AFAIK),但可以返回一个类。

因此,用法将变为:

const Node = createClass(...)
const node = new Node();

要获得此结果,createClass方法应返回一个新的类定义:

function createClass(options) {
  return class {
    constructor() {
      Object.assign(this, options.data, options.methods)
    }
  }
}

现在您可以执行以下操作:

const node = new Node();

node.translate(10, 15)
console.log(node.x)    // 10

node.translate(13, 15)
console.log(node.x)    // 23

顺便说一句,在ES6中,createClass方法在我看来可能真的很棒:)

const createClass = ({ data, methods }) =>
  class {
    constructor() {
      Object.assign(this, data, methods)
    }
  }