2017-03-17 5 views
0

クラスを実装するとき、実装されているメンバーはコンストラクタ内では使用できないことがわかりました。私はそれを間違って実装しているのか、本当に別のアプローチを取っているのかは分かりません。コンストラクタ(typescript)で実装されたメンバーを使用する

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

この:だから、あなたは最初のあなたがまだ割り当てられていないmyVarにアクセスしようとしているれているスーパーコンストラクタを呼び出す

class Child extends Parent { 
    myVar: number; 

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

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

は以下と等価です。

また、これはコンパイルの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)); 

あなたはParentコンストラクタでmyVarにアクセスできるようにしたい場合は、のような何かを行うことができます:

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ほとんどの場合、あなたは正しいですが、避けるのが難しい場合もあります。いずれにしても、私はここで事態の順序を説明しました。 –

関連する問題