ホームページ > 記事 > ウェブフロントエンド > jsクラス継承の具体的な実装方法_基礎知識
コードをいじり始める前に、継承を使用する目的と利点を理解する必要があります。一般に、クラスを設計するときは、コードの繰り返しを減らし、クラス間の結合を弱めるように努めます。両方のバランスをとることは困難であり、具体的な条件や状況に応じてどのような方法をとるかを決定する必要があります。オブジェクト指向言語における継承の理解によれば、継承はクラスの直接的な強結合をもたらしますが、js はその独特の柔軟性により、強結合と弱結合、高効率と低効率のコードを設計できます。何を使うかは状況によって異なります。
js で継承を実装するには、クラス継承、プロトタイプ継承、メタクラスの 3 つの方法があります。ここでは最初にクラス継承について簡単に説明し、最後の 2 つについては後で簡単に説明します。ご理解とご指導をお願いいたします。
古典的な継承。
js クラスの継承の実装は、プロトタイプ チェーンに依存します。プロトタイプチェーンとは何ですか? js のオブジェクトには、prototype と呼ばれる属性があり、この属性はオブジェクト タイプへの参照を返し、オブジェクトのクラスの基本関数のセットを提供するために使用されます。
プロトタイプの印象があるようです ちなみに、こんなコードをよく使います。
クラスの基本関数をプロトタイプ属性に配置し、Person オブジェクトへの参照に XXX 関数があることを示します。
プロトタイプを理解した後は、プロトタイプ チェーンとは何かを理解する必要があります。オブジェクトのメンバー (プロパティまたはメソッド) にアクセスするときに、このメンバーが現在のオブジェクト内に見つからない場合、js は、prototype 属性が指すオブジェクト内でそのメンバーを検索します。まだ見つからない場合は、引き続き検索します。次のレベルのプロトタイプを、指定されたオブジェクトが見つかるまで検索します。見つからない場合は、unknown が返されます。
では、プロトタイプチェーンはどのようなヒントを与えてくれるでしょうか?プロトタイプ チェーンとは、あるクラスが別のクラスを継承するには、親クラスのインスタンスを指すようにサブクラスのプロトタイプを設定するだけでよいことを意味すると考えるのは簡単です。これにより、親クラスのメンバーが子クラスにバインドされます。子クラスでメンバーが見つからない場合は、親クラスで検索されるためです。 (上記 2 つの段落の文言は厳密なものではなく、わかりやすく説明したものです)
次に、中国語クラスが必要です。これは、Person クラスの name メンバーと getName メンバーを継承する必要があります。
新しいオブジェクトを作成したり、インスタンスをインスタンス化して結合を弱めることができます。
これら 2 つの方法の違いは何ですか。 2 番目のタイプでは、空の関数 F が追加されます。これにより、親クラスのインスタンスの作成が回避されます。これは、親クラスが比較的大きい可能性があり、親クラスのコンストラクターに副作用が発生したり、大量の処理が実行されたりするためです。計算。したがって、2 番目の方法を強くお勧めします。
これで終わりです、まだ終わっていません!オブジェクトのプロトタイプ属性の下には属性コンストラクターがあり、特定のオブジェクト インスタンスを構築する関数への参照を保持します。このステートメントによると、Chiese.prototype.constructor は中国語と等しいはずですが、そうではありません。
Chiese のプロトタイプ チェーンをセットアップするときに、Chiese.prototype を person.prototype で上書きしたことを思い出してください。したがって、この時点の Chiese.prototype.constructor は person です。次のコードも追加する必要があります
すべてのコードを次のように整理します
継承したコードを関数に配置してコードの再利用を容易にできる場合、最終的なコードは次のように構成されます
公開後に改訂されました:
1 階のコメントの下に、拡張機能に関する新しい見解があります。以前、プロトタイプ チェーンのセットアップ方法について議論したときに 2 つの方法が提案されました
2 番目のメソッドは親クラスのコンストラクターを呼び出す必要性を減らしますが、中国語クラスの設計時に Person.call(this,name) が使用されました。これは親クラスのコンストラクターを呼び出すことと同じです。
ただし、最初の方法を使用すると、コードのこの部分はサブクラスで忘れられることがよくあります。この関数コードを extend に置くこともできます。
と書くだけですChinese.prototype = new Person(); も同じ目的を達成します。結合は強くありません。
しかし、忘れられているのは、 Chinese.prototype = new Person(); が正しく書かれていることです。答えはノーです!明らかに、 new Person() は name パラメータを渡す必要があります。この部分の作業は extend 関数では実行できないため、中国語クラスの親クラスのコンストラクターを呼び出す必要があります。これはオブジェクト指向の考え方とも一致しています。
したがって、やはり 2 番目の方法を使用することを強くお勧めします。
このような技術的な記事を書くのは初めてなので、基本的には自分の考えに基づいて開発していますが、考慮されていない部分や不明瞭な説明は避けられないと思います。フィードバック用のメッセージ、ありがとうございます。