jeremygo

jeremygo

我是把下一颗珍珠串在绳子上的人

[訳] JavaScript — 継承、デリゲートパターン、およびオブジェクトリンク

元の記事: JavaScript — Inheritance, delegation patterns and Object linking

著者: NC Patro

JavaScript(プロトタイプ継承)での継承、デリゲートパターン、および他のオブジェクトへのオブジェクトの関連付けの学習

継承とは#

ほとんどのクラスベースのオブジェクト指向言語では、継承は 1 つのオブジェクトが別のオブジェクトのすべてのプロパティとメソッドを取得できる仕組みです。ES2015ではclassキーワードが提案されましたが、JavaScriptはクラスベースの言語ではなく、本質的にはプロトタイプチェーンの方法です。

クラシック継承とプロトタイプ継承#

継承図

クラシック継承(非 JavaScript)#

  • Vehicleは親クラスであり、v1v2Vehicleのインスタンスです。
  • CarVehicleのサブクラスであり、c1c2Carのインスタンスです。
  • クラスを継承すると、クラシック継承では親クラスの振る舞いが子クラスにコピーされ、親子クラスは独立したエンティティになります。
  • これは、車がツールと車の図面で作られるが、完成した後はそれぞれが独立した個体であるため、コピーされるために関連性がないため、すべての矢印が下向き(プロパティと振る舞いが下に伝播する)理由です。

プロトタイプ継承(デリゲートパターン)#

  • v1v2Vehicle.prototypeに関連付けられています。これらはnewを使用して作成されたためです。
  • 同様に、c1c2Car.prototypeに関連付けられ、Car.prototypeVehicle.prototypeに関連付けられています。
  • JavaScriptでは、オブジェクトを作成すると、プロパティや振る舞いをコピーするのではなく、リンクを作成します。クラスを継承する場合も同様のリンクが作成されます。
  • クラシックな非JavaScriptの継承と比較して、すべてのリンクは逆方向に向かっているため、デリゲートリンクと呼ばれる行動委譲リンクです。これらのリンクはプロトタイプチェーンと呼ばれます。
  • このパターンはデリゲートパターンと呼ばれ、一般的にはJavaScriptでのプロトタイプ継承として知られています。

詳細については、この記事JavaScript - プロトタイプを参照してください。

プロトタイプ継承の例#

  • Object.create()を使用してクラシック継承を実装します。
  • 以下のコードスニペットでは、Object.create()関数のヘルプを使用してCar.prototypeVehicle.prototypeを接続します。
// Vehicle - スーパークラス
function Vehicle (name) {
    this.name = name;
}
// スーパークラスのメソッド
Vehicle.prototype.start = function () {
    return "engine of " + this.name + " starting...";
}

// Car - サブクラス
function Car (name) {
    Vehicle.call(this, name); // スーパークラスのコンストラクタを呼び出す
}
// サブクラスがスーパークラスを拡張
Car.prototype = Object.create(Vehicle.prototype);
// サブクラスのメソッド
Car.prototype.run = function () {
    console.log("Hello " + this.start());
}

// サブクラスのインスタンス
var c1 = new Car("Fiesta");
var c2 = new Car("Baleno");

// サブクラスのメソッドで内部的にスーパークラスのメソッドにアクセスする
c1.run();   // "Hello engine of Fiesta starting..."
c2.run();   // "Hello engine of Baleno starting..."
  • 上記のコードでは、以下のプロトタイプチェーンにより、オブジェクトc1run()メソッドとstart()メソッドにアクセスできることがわかります。次の図に示すように、c1にはそのようなメソッドはありませんが、上にリンクがあります。
  • 上記のコードのthisは、各メソッドの現在の実行コンテキスト、つまりc1c2です。

詳細については、この記事JavaScript-this と new についてのすべてを参照してください。

上記のコードの図解:

JavaScript 継承図

他のオブジェクトへの関連付け#

  • ここでは、以前の継承の例コードを簡略化し、オブジェクト間のリンクに焦点を当てます。
  • したがって、.prototypeconstructor、およびnewキーワードを削除し、オブジェクトのみを考慮します。
  • Object.create()関数を使用して関数間のすべてのリンクを作成します。

以下は、以前の例コードの簡略版です:

// 初期化メソッドを持つ基本オブジェクト
var Vehicle = {
    init: function (name) {
        this.name = name;
    },
    start: function () {
        return "engine of " + this.name + "starting...";
    }
}

// サブオブジェクトと基本オブジェクトの間に作成されたデリゲートリンク
var Car = Object.create(Vehicle);

// サブオブジェクトのメソッド
Car.run = function () {
    console.log("Hello " + this.start());
};

// デリゲートリンクを持つインスタンスオブジェクトはサブオブジェクトを指します
var c1 = Object.create(Car);
c1.init('Fiesta');

var c2 = Object.create(Car);
c2.init('Baleno');

c1.run();   // "Hello engine of Fiesta starting..."
c2.run();   // "Hello engine of Baleno starting..."

上記のコードの図解:

オブジェクトリンク

  • これで、new、すべての *.prototype*、コンストラクタ、およびメソッドの呼び出しの複雑さを排除し、同じ結果を実現できることがわかります。
  • 唯一重要なのは、c1がオブジェクトにリンクし、別のオブジェクトにリンクし、それ以降も同様に続くことです。
  • これはオブジェクトデリゲートパターンとも呼ばれます。

まとめ#

コード内でプロトタイプ継承とプロトタイプチェーンを使用する前に、それらを理解することは重要です。複雑さを回避するために。

参考文献: You Don't Know JS シリーズ

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。