Недавно я начал работать над игрой в Cocos Creator, которая использует TypeScript/JavaScript в качестве языка, в котором я новичок. Я пытаюсь создать сложный метод обратного вызова, который будет вызывать методы, прикрепленные к массиву объектов.
Вот краткий пример функциональности, которую я надеюсь достичь:
let arr:Base[] = [new Foo(), new Bar(), new FooBar()];
function func(interfaceType, method) {
arr.forEach(element => {
if (element instanceof interfaceType){
console.info(element.method());
}
});
}
func(BarI, bar()); //This should output bar foobar
func(FooI, foo()); //This should output 1 2
И все реализации интерфейса и класса
interface FooI{
foo():number;
foo2():string;
}
interface BarI{
bar():string;
}
class Base { }
class Foo extends Base implements FooI{
foo(): number {
return 1;
}
foo2(): string {
return "A";
}
}
class Bar extends Base implements BarI{
bar(): string {
return "bar";
}
}
class FooBar extends Base implements FooI, BarI{
foo(): number {
return 2;
}
foo2(): string {
return "B";
}
bar(): string {
return "foobar";
}
}
В этом блоке кода много проблем, например, instanceof не работает для интерфейсов, это не большая проблема, я нашел пару обходных путей (не самых элегантных, но не очень большая проблема). Настоящая проблема, с которой я столкнулся, - это вызов метода, я осмотрелся и нашел код для передачи функций/методов в качестве параметра, но он запускает параметр как независимую функцию, а не реализованный метод объекта.
Я получил этот пример, работающий с использованием отражений в Java, если вы хотите увидеть рабочий пример: Ссылка на Pastebin
К сожалению, вы не можете сделать
interface BarI{
bar():string;
}
if (element instanceof IBar) ...
поскольку интерфейсы не являются «настоящим» js-кодом. Вы могли бы сделать
class BarI{
bar(): string {
...
}
}
var element = new IBar()
if (element instanceof IBar) ...
Надеюсь, это поможет! Здесь тоже есть полезная информация
Спасибо Наркеку Дадуряну за ответ. я закончил тем, что сделал
let arr:Base[] = [new Foo(), new Bar(), new FooBar()];
function func(methodName) {
arr.forEach(element => {
if (element[methodName] !== undefined){
console.info(element[methodName]());
}
});
}
func("bar"); //This correctly output bar foobar
func("foo"); //This correctly output 1 2
Это также избавляет от необходимости проверять наличие интерфейсов, что хорошо, потому что имена методов не перекрываются при вызове соответствующих методов.