#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 — Я обновил ответ, учитывая, что вы готовы переписать определения классов