プロトタイプを使用して前の例のクラスを再定義すると、次の形式になります:
function ClassA() {
}
ClassA.prototype.color = "blue";
ClassA.prototype.sayColor = function () {
alert(this.color);
};
関数 ClassB() {
}
ClassB.prototype = new ClassA();
プロトタイプ アプローチの魔法は、コードの最後の行にあります。ここでは、ClassB のプロトタイプ プロパティを ClassA のインスタンスに設定します。これは興味深いものです。ClassA のすべてのプロパティとメソッドが必要ですが、それらを ClassB のプロトタイプ プロパティに 1 つずつ追加したくないからです。 ClassA のインスタンスをプロトタイプ プロパティに割り当てるより良い方法はありますか?
注: パラメータを渡さずに ClassA のコンストラクターを呼び出します。これはプロトタイプチェーンにおける標準的な慣行です。コンストラクターにパラメーターがないことを確認してください。
オブジェクトの偽装と同様に、サブクラスのすべてのプロパティとメソッドは、プロトタイプ プロパティが割り当てられた後に表示される必要があります。これは、プロトタイプ プロパティが割り当てられる前に割り当てられたすべてのメソッドが削除されるためです。なぜ?プロトタイプのプロパティが新しいオブジェクトに置き換えられるため、新しいメソッドが追加された元のオブジェクトは破棄されます。したがって、name 属性と SayName() メソッドを ClassB クラスに追加するコードは次のとおりです。
function ClassB() {
}
ClassB.prototype = new ClassA();
ClassB.prototype.name = "";
ClassB.prototype.sayName = function () {
alert(this.name);
};
はい次の例を実行して、このコードをテストします。
var objA = new ClassA();
var objB = new ClassB();
objA.color = "青";
objB.color = "赤";
objB.name = " John";
objA.sayColor();
objB.sayColor();
objB.sayName();
さらに、プロトタイプ チェーンでは、instanceof 演算子動作も非常にユニークです。 instanceof は、ClassB のすべてのインスタンスについて、ClassA と ClassB の両方に対して true を返します。例:
var objB = new ClassB( );
alert(objBinstanceofClassA); //出力 "true"
alert(objBinstanceofClassB); //出力 "true"
ECMAScript の弱い型付けの世界, これは非常に便利なツールですが、オブジェクトの偽装を使用する場合は使用できません。ただし、サブクラスのプロトタイプが直接再割り当てされるため、次の状況が発生します:
console.log(objB.__proto__===objB.constructor.prototype) //false
ClassB のプロトタイプ チェーンのプロトタイプ属性がオブジェクトによってオーバーライドされたため別のクラスの。出力結果は、objB.__proto__ が objB.constructor.prototype ではなく ClassB.prototype を指していることを示しています。これも分かりやすいですが、オブジェクトリテラルの new ClassA() インスタンスに代入されるのが、オブジェクトリテラルのメソッドで定義されたオブジェクトのコンストラクター(constructor)が、ルートコンストラクターの Object.prototype を指します。空のオブジェクト {}、{} は当然ながら ClassB.prototype とは異なります。