【问题标题】:Calling static method from non-static method in Typescript从 Typescript 中的非静态方法调用静态方法
【发布时间】:2020-09-15 22:04:34
【问题描述】:

我的所有层次结构中都有一些静态的东西(在这个例子中,_image)。我希望能够访问对应的_image 而无需重复代码:

这会很棒:

class Actor {
    static _image; // I need it to be static

    method show(){  // I need it to be non-static
        this.setImage(this.class._image); //doesn't work....
    }
}

class GoodActor extends Actor {
    static _image = 'good.png'
}

class BadActor extends Actor {
    static _image = 'bad.png'
}

class MediumActor extends Actor {
    static _image = 'medium.png'
}

但它不起作用。现在我只需要:

class Actor {
}

class GoodActor extends Actor {
    static _image = 'good.png'  // I need it to be static

    method show(){   // I need it to be non-static
        this.setImage(GoodActor._image);
    }
}

class BadActor extends Actor {
    static _image = 'bad.png'  // I need it to be static

    method show(){  // I need it to be non-static
        this.setImage(BadActor._image);
    }
}

class MediumActor extends Actor {
    static _image = 'medium.png'  // I need it to be static

    method show(){  // I need it to be non-static
        this.setImage(MediumActor._image);
    }
}

假设这四个类有更多的方法。我不想在每个子类中重复 show() 方法...但是我 需要 show() 方法是 非静态 和 @987654328 @ 被静态访问

我已经阅读了这个问题https://github.com/Microsoft/TypeScript/issues/7673,但不幸的是我不能在那里问,因为他们没有修复它就关闭了它。他们都没有谈到需要动态解析要调用的静态方法的问题。

【问题讨论】:

  • 为什么你需要让它保持静态?对可变事物使用静态变量通常会尖叫“有问题”。
  • 嗨!是的,我知道这有点奇怪。这是一个网络游戏。我需要在构建演员之前拥有演员的图像,以便能够预加载它们。建议接受:)
  • 将图像放置在某种与这些无关的静态对象中并从那里加载它们。

标签: typescript static-methods template-method-pattern


【解决方案1】:

FTR,你可以访问当前对象的类。它被称为constructor,而不是class,您需要声明它,使其具有比Function 更有用的类型。

class Actor {
    static _image: string; // I need it to be static

    // Keep static members, remove construct signature because
    // subclasses may define constructors with different parameters. 
    "constructor": Pick<typeof Actor, keyof typeof Actor>;

    show(){  // I need it to be non-static
        this.setImage(this.constructor._image);
    }
}

class GoodActor extends Actor {
    static _image = 'good.png'
}

class BadActor extends Actor {
    static _image = 'bad.png'
}

class MediumActor extends Actor {
    static _image = 'medium.png'
}

【讨论】:

  • 谢谢!又学到了一些东西。
【解决方案2】:

更新:您为什么不想在缓存图像之前构造单个对象?如果您使构建成本低廉,则使用静态字段没有任何好处。

例子:

class Actor {
    image: string;

    showImage() {
        console.log(this.image);
    }
}


class GoodActor extends Actor {
    image = 'good.png';
}

class BadActor extends Actor {
    image = 'bad.png';
}

const myActorTypes: (typeof Actor)[] = [GoodActor, BadActor];

function preloadImages() {
    for (let myActorType of myActorTypes) {
        preloadImage(new myActorType().image);
    }
}

function preloadImage(image: string) {
    console.log(`Loading ${image}`);
}

preloadImages();

// "Loading good.png"
// "Loading bad.png"

【讨论】:

  • 在您所做的新更新中,您达到了我正在处理的确切点。这正是我想要做的:将类放在一个数组中,然后对它们进行 forEach。问题在于,正如您所指出的,这里的建设昂贵的。当您执行 new myActorType() 时,actor 会显示自己。构造函数执行 this.show() 并计算一堆东西。而在游戏中,你需要不同时刻的演员……你不会同时想要他们。改变这个设计现在是一项相当大的工作。我正在尝试找到一些解决方法。现在我已经学会了“不要有昂贵的建筑”,以备将来之用。
  • 我会继续重构代码。它将为您将要做的任何其他事情节省很多痛苦(想想:列出演员姓名,任何类型的列表)。有了一个可以重构的像样的 IDE,我希望它不会太难。
  • 我现在选择实例化每个参与者,我将为所需的重构创建一个问题。非常感谢!!!
  • 编译时间是什么意思?
  • @AluanHaddad 编译器编译的时间范围。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-04
  • 1970-01-01
  • 1970-01-01
  • 2013-03-20
相关资源
最近更新 更多