POV
POV

Reputation: 12005

How to create instance of class by name or type?

I have the following structure of classes:

class FilterWeekScheduleClass {

}

class FilterClassJournal { 

}

const registryFilterClasses = {
  FilterWeekScheduleClass,
  FilterClassJournal
};

class SingletonClassRegister {
  public registeredClasses = {};

  public constructor() {
    for (let obj in registryFilterClasses) {
      // CREATE INSTANCE OF obj LIKE new obj();
    }
  }
}

let a = new SingletonClassRegister();

In constructor of SingletonClassRegister class, I try to create instance based on registryFilterClasses. How to create instances proper?

I tried to do this:

class SingletonClassRegister {
  public registeredClasses = {};

  public constructor() {
    for (let obj of registryFilterClasses) {
      registryFilterClasses[obj.constructor.name] = new obj();
    }
  }
}

Is it right?

Upvotes: 1

Views: 1555

Answers (1)

Christoph Lütjen
Christoph Lütjen

Reputation: 5804

First I think you want an array, so let's fix registryFilterClasses:

const registryFilterClasses = [
  FilterWeekScheduleClass,
  FilterClassJournal
];

Then simply create the instances:

for (let cls of registryFilterClasses) {
  let myInstance = new cls();
}

Or the same with an object as data source:

const registryFilterClasses = {
  FilterWeekScheduleClass,
  FilterClassJournal
};
// see https://eslint.org/docs/rules/object-shorthand
// same as
//    const registryFilterClasses = {
//      FilterWeekScheduleClass: FilterWeekScheduleClass,
//      FilterClassJournal: FilterClassJournal
//    };

for (let key in registryFilterClasses) {
  // key is now the name of the class as string
  let myInstance = new registryFilterClasses[key]();
}

Update: Get class name:

class Test {}
Test.name => "Test"

const t = Test;
t.name => "Test"

const i = new t();
i.constructor.name => "Test"

Possible implementation for your registry:

class SingletonClassRegister {
  public registeredClasses = {
    MyClass
  };

  private instances = {};

  getInstanceByClassName(name) {
    if(this.instances[name] == undefined)
      this.instances[name] = new this.registeredClasses[name]();
    return this.instances[name];
  }

  getInstancesForAllRegisteredClasses() {
    return Object.keys(this.registeredClasses)
       .map(name => this.getInstanceByClassName(name));
  }
}

Upvotes: 2

Related Questions