如何从TypeScript中的受保护方法访问私有实例变量

时间:2018-08-24 23:35:07

标签: javascript typescript methods abstract getter-setter

我有一个抽象类,该抽象类具有由子类实现的抽象方法。子类中的已实现方法应更新子类的私有实例变量。之后,我要使用getter方法检索私有变量的值。

要查看实际存在的问题,我创建了some sample code in playground

动物是具有抽象方法 someAbstractMethod()的基类:

abstract class Animal {

    protected abstract someAbstractMethod(): void;

    constructor() {
        document.writeln("A new animal is born<br>");
        this.someAbstractMethod();                          //  <-- call into child class
    }  
}

继承自Animal,并实现了抽象方法 someAbstractMethod()。此类有一个getter / setter来检索私有实例变量 someLocalVariable 的值:

class Snake extends Animal {

    private someLocalVariable: string = "intial value";

    constructor() {
        super();
    }

    get someValue() {
        document.writeln("Called getter for someValue<br>");
        return this.someLocalVariable;
   }

    set someValue(value: string) {
        document.writeln("Called setter for someValue<br>");
        this.someLocalVariable = value;
    }

    protected someAbstractMethod() {
        document.writeln("Called someAbstractMethod()<br>");
        this.someLocalVariable = "now set to something new";        //   <-- instance variable not updated (or in another scope)
    }
}

首先创建一个新的Snake,然后使用对 sam.someValue 的getter调用来获取私有实例变量的值:

let sam = new Snake();
document.writeln("Value of someValue: " + sam.someValue);   

意外结果

打印日志:

    A new animal is born
    Called someAbstractMethod()
    Called getter for someValue
    Value of someValue: intial value

sam.someValue 返回'初始值',但是实际上 someAbstractMethod()方法是在之前调用的,因此应将其值设置为“现在设置为新内容”

1 个答案:

答案 0 :(得分:0)

阅读this related question后,我找到了问题的答案。

我的解决方案

唯一的变化是在课程 Snake 中。我已经删除了对变量 someLocalVariable 的分配。

class Snake extends Animal {

    private someLocalVariable: string; // = "intial value";         <--- remove assignment

    constructor() {
        super();
    }

    get someValue() {
        document.writeln("Called getter for someValue<br>");
        return this.someLocalVariable;
    }

    set someValue(value: string) {
        document.writeln("Called setter for someValue<br>");
        this.someLocalVariable = value;
    }

    protected someAbstractMethod() {
        document.writeln("Called someAbstractMethod()<br>");
        this.someLocalVariable = "now set to something new";
    }
}

Updated code in playground

问题是 someLocalVariable 的初始化是在构造函数调用之后完成的。 someAbstractMethod()是从super.constructor调用的,实际上它正确设置了值,但随后它从构造函数返回,此后,私有实例变量用“ inital value” < / em>。通过删除分配,从ctor返回后, someLocalVariable 的值保持不变。

但是此解决方案仍然存在问题,因为如果启用了编译器选项--strictPropertyInitialization--strictNullChecks,则编译将失败。 对我来说,这个事实目前还可以,但感觉好像我做错了。