2015-09-30 4 views
4

Я использую babel.js traspiler для написания кода ES6.Динамически выбирайте класс из строки - «MyClassName» -> MyClassName

У меня есть строка, содержащая имя класса. Мне нужен класс, который я могу создать. Как?

Я пробовал:

eval("MyClassName") -> :(
window["MyClassName"] -> :(

Есть идеи?

+0

Какую модульную систему вы используете с Babel? По умолчанию это обычный JS, поэтому все [на этой странице] (https://babeljs.io/docs/usage/modules/#common-default-) будет работать. – CodingIntrigue

+0

Это невозможно. – Ginden

+1

Можете ли вы рассказать о том, почему вы хотите это сделать? В зависимости от usecase могут быть варианты, но в целом, как вы видели, ответ - нет, без 'eval'. – loganfsmyth

ответ

2

Вы можете:

Поскольку с BabelJS вы должны transpile на модуль загрузчика ES5, было бы так просто, как (в зависимости от module format вы указали во время transpile):

const MyClassName = require("MyClassName"); 
const obj = new MyClassName(); 

Однако это не ES6, но пресечено ES5. Таким образом, ваш код не будет работать в реальных средах ES6.

В среде ES6 class просто синтаксический сахар для функции, так что нет никаких причин, вы не можете сделать:

// Class definition 
class MyClassName { } 
// Pollute global scope 
(global || window).MyClassName = MyClassName; 

И загрузить его следующим образом:

const instance = new (window || global)["MyClassName"](); 

Но при этом поэтому вы только что сломали основные функциональные модули, дайте вам в первую очередь.

Вы должны:

Создание фабрики класса. В большинстве случаев количество классов, которые вы можете создать, конечно. Вы должны создать фабричную функцию, которая дает вам экземпляр класса, основанный на шнурке:

import MyClassName from "./MyClassName" 
class MyFactory { 
    static getInstance(value) { 
     if(value === "MyClassName") { 
      return new MyClassName(); 
     } 
     throw new Error(`Could not instantiate ${value}`); 
    } 
} 

, который будет использоваться как:

import MyFactory from "./MyFactory"; 
const instance = MyFactory.getInstance("MyClassName"); 

Очевидно, что вы могли бы расширить, что использовать Map вместо строка if заявлений, но вы получите эту идею.

+0

Спасибо за это! Очень вдумчивый ответ. Я просто искал то же самое, и я нашел эту нить (классику) и только понял, что не видел вашего уведомления. Я смотрю на ту же часть кода, что мне не нравится. Это то, что вы описали в «You Should». Ну, я продолжу добавлять к фабричному классу. –

+0

Есть ли причина, почему завод должен быть классом? Могу ли я не просто использовать заводскую функцию? – Kryten

+0

Нет причин вообще. Оглядываясь назад на этот ответ, я бы сейчас не выбрал синтаксис класса. Регулярная функция будет работать так же хорошо. – CodingIntrigue

Смежные вопросы