2017-03-17 39 views
0

我发现在实现一个类时,实现的成员在构造函数中不可用。我不知道我是否执行错误,或者如果我真的应该采取不同的方法。在构造函数中使用已实现的成员(打字稿)

abstract class Parent { 
    abstract myVar: number; 

    constructor() { 
    console.log(this.myVar) // Outputs undefined 
    } 

    f() { 
    console.log(this.myVar) // outputs 5 
    } 
} 

class Child extends Parent { 
    myVar: number = 5; 
} 

let myChild = new Child; 
myChild.f(); 

我该如何在构造函数中访问这些实现的成员?

回答

1

基类的构造将无法在自己的执行过程中看到派生类的字段。

您可以使用此模式来代替:

abstract class Parent { 
    constructor(public myVar: number) { 
    console.log(this.myVar) // Outputs 5 
    } 

    f() { 
    console.log(this.myVar) // outputs 5 
    } 
} 

class Child extends Parent { 
    constructor() { 
     super(5); 
    } 
} 

let myChild = new Child; 
myChild.f(); 
1

此:

class Child extends Parent { 
    myVar: number = 5; 
} 

等同于:

class Child extends Parent { 
    myVar: number; 

    constructor() { 
     super(); 
     this.myVar = 5; 
    } 
} 

所以你首先调用超构造函数,在你试图访问其尚未分配myVar

这也是从编译JS明确:

var Parent = (function() { 
    function Parent() { 
     console.log(this.myVar); 
    } 
    Parent.prototype.f = function() { 
     console.log(this.myVar); 
    }; 
    return Parent; 
}()); 
var Child = (function (_super) { 
    __extends(Child, _super); 
    function Child() { 
     var _this = _super !== null && _super.apply(this, arguments) || this; 
     _this.myVar = 5; 
     return _this; 
    } 
    return Child; 
}(Parent)); 

如果您希望能够访问myVarParent构造函数,你可以这样做:

abstract class Parent { 
    abstract myVar: number; 

    constructor() { 
     this.init(); 
     console.log(this.myVar); 
    } 

    f() { 
     console.log(this.myVar); 
    } 

    protected abstract init(); 
} 

class Child extends Parent { 
    myVar: number; 

    protected init() { 
     this.myVar = 5; 
    } 
} 
+1

不调用从构造一个虚拟的方法的忠实粉丝。派生类可能会调用一个基类方法,它的行为将是未定义的,因为基类仍处于部分初始化状态。 –

+0

@RyanCavanaugh在大多数情况下,你是对的,但有时很难避免。无论如何,我在这里用它来说明事情发生的顺序。 –

相关问题