2016-09-25 1 views
1

私は既存のプロトタイプ階層を持っています。それを変更して、階層を元の状態に保ちながら追加プロトタイプを追加します。 instanceofはすべてのプロトタイプに対してtrueを返す必要があります。既存のプロトタイプチェーンに基底クラスを追加して、instanceofが動作するようにします。

私は:私はB-> Aを持っていて、B-> A-> Baseにしたいと言っています。今度はinstanceofはA、B、Baseに対してtrueを返すべきです。

私はB.prototype.prototypeとObject.setPrototypeOf()を使用しようとしましたが、どちらの場合も運がありません。 Object.setPrototypeOfと

サンプル():

class A {                                                        
    do() { console.log("do A"); }                                                        
}                                                          


class B extends A { 
    do() { console.log("do B"); } 

    doB() { console.log("what"); } 
} 


var a = new A(); 
var b = new B(); 

a.do(); 
b.do(); 
b.doB(); 

console.log(a instanceof A) // true 
console.log(a instanceof B) // false 

console.log(b instanceof A) // true 
console.log(b instanceof B) // true 


class Base { 
    doBase() { console.log("this is the base!"); } 
} 


// now add Base to B's chain, so that B -> A -> Base 
// TODO: doesn't work! 

Object.setPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(B)), Base.prototype) 
//Object.setPrototypeOf(Object.getPrototypeOf(B), Base) 


console.log(Object.getPrototypeOf(B)) 
console.log(Object.getPrototypeOf(Object.getPrototypeOf(B))) 


var c = new B(); 

console.log(c instanceof B) // true 
console.log(c instanceof A) // true 
console.log(c instanceof Base) // false (!!! how to fix it?) 

c.doBase();     // crash, not a function 
+1

これは狂っています。なぜあなたはそれをしたいのですか? 'Base'のインスタンスを作成し、それを' B'のサブクラスにするのはなぜですか?それはOOのポイントになります。 – idmean

+0

"*階層を元の状態に保つように修正したい*" - これは不可能です。 'A'はもともと' Object'から継承していましたが、 'Base'から継承するべきですか?それは "そのまま"ではありません。 – Bergi

+0

はい、本当にクレイジーです。そして私の選択ではありません。古いフレームワークを修正してES6クラスで使用できるようにしようとしています。上記のフレームワークは、すべてのユーザーコンポーネントをComponent基本クラスで拡張しますが、プロトタイプを上書きして元のすべてのプロパティをコピーして戻します。これで、Componentから継承されて元のクラスが失われているように見えます。それで、バベルが '_classCallCheck'を生成するので、私はもうインスタンス化できません。 – MiB

答えて

1

これはにBからの継承関係を示しています。

console.log(Object.getPrototypeOf(B.prototype) === A.prototype); 

です。

class A { do() { console.log("do A"); } } 

class B extends A { 
    do() { console.log("do B"); } 
    doB() { console.log("what"); } 
} 

class Base { 
    doBase() { console.log("this is the base!"); } 
} 

Aを参照しない場合は、これが必要です。

Object.setPrototypeOf(Object.getPrototypeOf(B.prototype), Base.prototype); 

です。

console.log(new A() instanceof Base); // true 
console.log(new B() instanceof Base); // true 
(new B()).doBase(); // this is the base! 

どのようにですか?それを再生するhere

Aを参照せずにクラス拡張と同じ方法でObject.setPrototypeOf(A,Base)を達成するために、Bergiが述べたように、Object.setPrototypeOf(Object.getPrototypeOf(B.prototype.constructor), Base)。 (調査する必要があり、循環継承エラーが発生したと報告されています...)

上記のように、クラスのコンストラクタ継承を実行するようにテストhereを拡張しました。 Chrome 53(V8 5.3.332.45)で動作します。

編集:これは、継承チェーンを猿でパッチしていることに注意してください。それはパフォーマンスにとって素晴らしい考えではありません。

+0

'Object.setPrototypeOf(A、Base)'を忘れないでください。 – Bergi

+0

なぜそうするのですか? – TylerY86

+0

いいアイデア!私の問題はまさに私がその時点でAについて知りません。私が得るのはBへの参照ですが、今度はAについて知り、プロトタイプを設定する必要があります。 – MiB

関連する問題