BaoYukun
BaoYukun

Reputation: 13

How to generate a class from a descriptive object dynamically?

I'm trying to accomplish a function that receives an object as parameter and returns a class (or a constructor) generated based on the descriptive object received. Is there any resolvent without using '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();

I've accomplished one version by 'eval' function. I want to know if there is any other better ways to do this. Thanks for you help.

Upvotes: 0

Views: 47

Answers (2)

0xc14m1z
0xc14m1z

Reputation: 3725

You can take advantage of Javascript clojures, but you have to have a slightly different behavior: you cannot define a class globally (AFAIK), but you can return one.

So, the usage will become:

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

To get this result, the createClass method should return a new class definition:

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

Now you can do something like:

const node = new Node();

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

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

BTW, in ES6 the createClass method can become really wonderful in my opinion :)

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

Upvotes: 0

CertainPerformance
CertainPerformance

Reputation: 371019

Instead of standalone, dynamic variable names, consider using an object of classes instead, indexed by the class names (like Node) so that you can do something like 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);

Upvotes: 1

Related Questions