JS Рефлексия. Как создать экземпляр класса по его названию?

Я разрабатываю мини-фреймворк на JS для решения своей задачи. Мне нужно создать экземпляр класса по его названию (или возможно есть какой-то более удобный способ). Например:

class MyClass{
    constructor(a, b) {
        this.a = a;
        this.b = b;
    }
}

let className = 'MyClass';

let args = [5, 10]

let instance = createClassByName(className, args);

Ответы (1 шт):

Автор решения: OPTIMUS PRIME

Нужно сохранить все необходимые классы в каком-нибудь объекте в глобальной области. После инициализации каждого класса: myObject.MyClass = MyClass; И позже можно будет вызывать new (myObject[className])(...args);

Не будет ничего плохого, если прямо так и прописать всё в коде. Но можно придумать и вариации чего-то подобного:

const CLASS = {
  _storage: {/*
    className1: class,
    className2: class,
  */},
  
  create: function(className, ...args) {
    let _class_ = this._storage[className];
    
    return new _class_(...args);
  },
  
  save: function(_class_) {
    let name = _class_.name;
    if (!name) throw new Error("Expected named class");
    if (name in this._storage) throw new Error("Name conflict: " + name);
    
    return this._storage[name] = _class_;
  },
};

/***/
const MyClass = CLASS.save(class MyClass {
  constructor(a, b) {
    this.a = a;
    this.b = b;
  }
});

let args = [5, 10];
let instance = CLASS.create('MyClass', ...args);

console.log(instance.a, instance.b); // 5 10

// const MyClass = CLASS.save(class MyClass extends Super { });


Предложенную вами функцию можно выполнить и через великий и ужасный eval(), который выполняет код из строки и которого предлагают всячески избегать. (* Пусть на всякий случай удаляет всё, что не может быть названием переменной )

function createClassByName(className, args) {
  className = className.replace(/[^$\w]/g, '');  
  return eval(`new ${ className }(...${ args })`);
}

Ограничение: В этом случае все классы должны быть видны в глобальной области. В предыдущем варианте они могут быть закрыты в разных областях, но вызываться из любого места.

→ Ссылка