Как создать экземпляр класса с помощью переменной

#javascript #typescript #object #ecmascript-6

#javascript #typescript #объект #ecmascript-6

Вопрос:

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

Например, если у нас есть . . .

 class MyClass {    
   someFunc(){alert("Hello");}    
}
var myClassName = "MyClass";
  

Ответы предположительно были либо:

Ответ # 1:
var myClassInstance = new (<any>window)[myClassName]();

Ответ # 2:
var myClassInstance = Object.create(window[myClassName]);

Я пробую это в своей консоли, но ни то, ни другое у меня не работает.
Для # 1 я получаю сообщения об ошибках: «Синтаксическая ошибка», или, если я опускаю <any> , «Объект не поддерживает это действие».
Для # 2 я получаю сообщения об ошибках: «Object.create: аргумент не является объектом и не равен null»

Есть ли у кого-нибудь идеи, почему у меня это не работает и / или как я могу создать экземпляр класса в Typescript на основе значения переменной, которая содержит имя класса? Спасибо!

Комментарии:

1. class / let и const не похожи на старые function и var , которые могут «загрязнять» глобальное пространство имен (window в вашем случае)… когда вы говорите «ответы, предположительно, были» … по мнению кого?

2. @JaromandaX Виноват. Неправильно сформулировал вопрос

Ответ №1:

Вы не можете сделать это с class — вам пришлось бы использовать конструктор ES5:

 function MyClass() {}
MyClass.prototype.someFunc = function() {
  alert("Hello!");
};
var myClassName = "MyClass";
var myClassInstance = new window[myClassName]();
myClassInstance.someFunc();  

Ответ №2:

Причина, по которой эти «ответы» не работают, заключается в том, что MyClass не является свойством глобального объекта (window в вашем случае)

Это верно и для переменных, объявленных в глобальной области видимости с помощью let и const , а также

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

Примечание: используйте var не let или const

 var MyClass = class MyClass {    
   someFunc(){alert("Hello");}
}
var AnotherClass = class AnotherClass {    
   someFunc(){alert("Hello again");}
}
var YetAnotherClass = class YetAnotherClass {    
   someFunc(){alert("Hello once more");}
}
  

Затем вы можете просто

 let instance = new window[myClassName]();
  

Кроме того, в зависимости от того, где / как определены классы (при импорте?), на самом деле может потребоваться сделать что-то вроде

 window.MyClass = class MyClass {    
   someFunc(){alert("Hello");}
}
  

вместо

Комментарии:

1. Большое спасибо за ответ. Я надеялся создавать экземпляры классов «на лету», просто предоставляя переменной имя класса, без необходимости предварительной загрузки каких-либо констант, конструкторов или другого кода, так что, если в будущем я добавлю новые классы или изменю структуру (свойства) существующего класса, мой код будет легко обрабатывать это во время выполнения, без необходимости переписывать какой-либо другой код. Но я начинаю думать, что на данный момент это может быть нереалистичной целью.

2. @Crowdpleasr — Я обновил ответ, учитывая, что вы готовы переписать определения классов