Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   ES6. Create class instance by name (https://javascript.ru/forum/misc/75535-es6-create-class-instance-name.html)

Nexus 17.10.2018 11:38

ES6. Create class instance by name
 
Можно ли в es6 как-то создать экземпляр класса, если известно только его наименование?

class SomeClass{};

const className='SomeClass';
const instance=new window[className]();//win[className] - undefined

Dilettante_Pro 17.10.2018 11:58

Nexus,
а что, нельзя
class SomeClass{};
const instance=new SomeClass();

???

Nexus 17.10.2018 12:02

Dilettante_Pro, нет, нельзя.
У меня есть только data-атрибут, в котором содержится наименование сущности, для которой нужно подгрузить и инициализировать адаптер.
Т.е. наименование класса динамичное.

Пока что вижу выход только в использовании eval.

destus 17.10.2018 12:05

class SomeClass{};

const className='SomeClass';
const obj = (Function('return new ' + className))()
alert(obj instanceof SomeClass);

Nexus 17.10.2018 12:11

destus, спасибо, только что тоже самое написал.
/**
		 * @param {string} engine
		 * @param {string|jQuery} $node
		 * @return {AbstractAdapter}
		 */
		static get(engine,$node){
			const adapterName=engine.substr(0,1).toUpperCase()+engine.substr(1).toLowerCase();
			const constructor=new Function('$node','return new '+adapterName+'Adapter($node);');

			return constructor($node);
		}

Плюсануть в карму, к сожалению, не могу из-за ограничений сайта.

Nexus 17.10.2018 12:14

Все же создание и вызов функции, которая вернет экземпляр класса не сильно отличается от eval.
Более "цивилизованного" способа получить экземпляр класса по его имени нет?

SuperZen 17.10.2018 15:19

// definition
import One from './One'
import Two from './Two'

const classes = { One, Two }

export default function dynClass(name) {
  return classes[name]
}

// usage
import dynClass from './dynClass'

const UnknownClass = dynClass('One')

new UnknownClass(props)

Nexus 17.10.2018 15:30

SuperZen, спасибо, я видел этот костыль.

Dilettante_Pro 17.10.2018 16:29

Может, создать свой namespace для классов?
class SomeClass {
  constructor(name) {
    this.name = name;
  }
  sayHi() {
    alert(this.name);
  }
}

const classNS = {
  'SomeClass': SomeClass
};


let user = new classNS['SomeClass']("Вася");
user.sayHi();

Nexus 17.10.2018 16:50

Dilettante_Pro, тогда уж лучше так классы объявлять:
var SomeClass=(function(){
	class SomeClass{
		getName(){
			return this.constructor.name;
		}
	};

	return SomeClass;
})();

class ClassFactory{
	static createClass(name){
		return new window[name]();
	}
}

console.log(
	ClassFactory.createClass('SomeClass').getName()
);


Часовой пояс GMT +3, время: 11:21.