JavaScript の継承についてどれくらい知っていますか?

JavaScript の継承についてどれくらい知っていますか?

序文

継承についてどれくらい知っていますか?どのような継承が最適でしょうか?継承に関するいくつかの知識ポイントを学び、その実装プロセスと利点と欠点を紹介します。

コンストラクタ、プロトタイプオブジェクト、インスタンスオブジェクトの関係

まずそれらの関係を理解することで、継承をよりよく理解できるようになります

プロトタイプチェーン継承

コア: 親クラスのインスタンスをサブクラスのプロトタイプとして使用する

コード実装プロセス:

関数 Parent(名前){
    this.name = 名前 || 'xt',
    this.arr = [1]
}
関数Son(年齢){
    this.age = 年齢
}
Parent.prototype.say = function() { //親クラスのプロトタイプで再利用および共有する必要があるメソッドを定義します。console.log('hello');
}
Son.prototype = 新しい親()
s1 = 新しいSon(18)とする
s2 = new Son(19)とする
console.log(s1.say() === s2.say()); //true
console.log(s1.name,s1.age); //xt 18
console.log(s2.name,s2.age); //xt 19
s1.arr.push(2)
console.log(s1.arr,s2.arr); // [ 1, 2 ] [ 1, 2 ]

アドバンテージ:

インスタンスが継承できる属性は、インスタンスのコンストラクターの属性、親クラスのコンストラクターの属性、および親クラスのプロトタイプの属性です。 (新しいインスタンスは親クラス インスタンスのプロパティを継承しません!)

欠点:

  • サブクラスのインスタンスは、arr プロパティなどの親クラスのコンストラクターの参照プロパティを共有します (プロトタイプのプロパティは共有され、1 つのインスタンスがプロトタイプ プロパティを変更すると、他のインスタンスのプロトタイプ プロパティも変更されます)。
  • 親クラスのコンストラクタにパラメータを渡すことができません

コンストラクタ継承の借用

コア: 親クラスのコンストラクターを使用して子クラスのインスタンスを拡張します。これは、親クラスのインスタンス属性を子クラスにコピーすることと同じです。

コード実装:

関数 親(名前) {
    this.name = 名前;
    this.arr = [1],
    this.say = function() { console.log('hello') }
}
関数 Son(名前, 年齢) {
    Parent.call(this, name) //親クラスのインスタンスプロパティとメソッドをコピーします this.age = age
}
s1 = new Son('小谭', 18) とします。
s2 = new Son('Xiaoming', 19) とします。
console.log(s1.say === s2.say) //false メソッドは再利用できません。メソッドは独立しており、共有されていません。 console.log(s1.name, s1.age); //Xiao Tan 18
console.log(s2.name, s2.age); //Xiaoming19
s1.arr.push(2)
console.log(s1.arr, s2.arr); // [ 1, 2 ] [ 1 ]

アドバンテージ:

  • 親クラス コンストラクターのプロパティのみを継承し、親クラス プロトタイプのプロパティは継承しません。
  • 複数のコンストラクタプロパティを継承できる(複数呼び出し)
  • 子インスタンスでは、パラメータを親インスタンスに渡すことができます。

欠点:

  • 親クラスのコンストラクターからのみプロパティを継承できます。
  • コンストラクタの再利用はできません。 (使用するたびに再度呼び出す必要があります)
  • それぞれの新しいインスタンスには、肥大化した親クラスのコンストラクターのコピーが含まれます。

プロトタイプ継承

コア: オブジェクトを関数でラップし、この関数の呼び出しを返します。この関数は、任意に属性を追加できるインスタンスまたはオブジェクトになります。

関数 親(名前) {
    this.name = 'xt';
    this.arr = [1]
}
関数オブジェクト(obj){
    関数 F(){}
    F.プロトタイプ = obj;
    新しいF()を返します。
  }
s1 = 新しい親(オブジェクト)
s1.name = 'シャオミン'
s1.arr.push(2)
s2 = 新しい親(オブジェクト)
console.log(s1.name,s2.name); // Xiaoming xt
console.log(s1.arr, s2.arr); //[ 1, 2 ] [ 1 ]

欠点:

  • すべてのインスタンスはプロトタイプのプロパティを継承し、パラメータを渡すことはできません。
  • 再利用はできません。 (新しいインスタンス属性は後で追加されます)

寄生遺伝

コア: プロトタイプ継承に基づいてオブジェクトを拡張し、コンストラクタを返す

関数 親(名前) {
    this.name = 'xt';
    this.arr = [1]
}
関数オブジェクト(obj){
    関数 F(){}
    F.プロトタイプ = obj;
    新しいF()を返します。
  }
息子 = 新しい親()
関数addobject(obj){
    var add = オブジェクト(obj)
    add.name = 'シャオバイ'
    戻る追加
}
var s1 = addobject(息子)
console.log(s1.name); //小白

欠点:

  • プロトタイプは使用されず、再利用できません。
  • プロトタイプ チェーンによって継承された複数のインスタンスの参照型プロパティは同じものを指すため、改ざんが発生する可能性があります。

結合継承(プロトタイプチェーン継承と借用コンストラクタ継承の組み合わせ)

コア: 親クラスのコンストラクターを呼び出すことで、親クラスのプロパティが継承され、パラメーター渡しの利点が保持されます。次に、親クラスのインスタンスをサブクラスのプロトタイプとして使用することで、関数の再利用が実現されます。

コード実装:

関数 親(名前) {
    this.name = 名前;
    this.arr = [1]
}
Parent.prototype.say = function () { console.log('hello') }
関数 Son(名前, 年齢) {
    Parent.call(this, name) // 2回目 this.age = age
}
Parent.prototype = new Son() // 一度、let s1 = new Son('小谭', 18)
s2 = new Son('Xiaoming', 19) とします。
console.log(s1.say === s2.say) // 真
console.log(s1.name, s1.age); //シャオタン18
console.log(s2.name, s2.age); //Xiaoming19
s1.arr.push(2)
console.log(s1.arr, s2.arr); // [ 1, 2 ] [ 1 ] は親クラスの参照プロパティを共有しません。

アドバンテージ:

  • コンストラクターを保持する利点: サブクラスのインスタンスを作成するときに、親クラスのコンストラクターにパラメーターを渡すことができます。
  • プロトタイプ チェーンを保持する利点: 親クラスのメソッドは親クラスのプロトタイプ オブジェクト上で定義されるため、メソッドの再利用を実現できます。
  • 親クラスの参照プロパティは共有されません。例えば、arr属性

欠点:

  • 親クラスのコンストラクターが 2 回呼び出されるため、冗長な親クラスのインスタンス属性が存在することになります。

寄生的組み合わせ継承

コア: パラメータを渡すための借用コンストラクタと継承を実現するための寄生パターンを組み合わせる

関数 Parent(名前){
    this.name = 名前 || 'xt',
    this.arr = [1]
}
関数 Son(名前,年齢){
    Parent.call(this,name) // コア
    this.age = 年齢
}
Parent.prototype.say = function() {  
    コンソールにログ出力します。
}
Son.prototype = Object.create(Parent.prototype) // コアは中間オブジェクトを作成し、子クラスのプロトタイプと親クラスのプロトタイプは分離されます。
Son.prototype.constructor = Son
p1 = 新しい親()

s1 = new Son("Xiaohong",18) とします。
s2 = new Son("小黒",19) とします。
console.log(p1.constructor); //[関数: 親]
console.log(s1.constructor); // [関数: Son]
console.log(s1.say() === s2.say()); //true
console.log(s1.name,s1.age); // シャオホン 18
console.log(s2.name,s2.age); //リトルブラック19
s1.arr.push(2)
console.log(s1.arr,s2.arr); // [ 1, 2 ] [ 1, 2 ]

寄生的合成継承は参照型継承の最良の継承とみなすことができる

要約する

JS継承に関する記事はこれで終了です。JS継承についてさらに詳しく知りたい方は、123WORDPRESS.COMの過去の記事を検索するか、以下の関連記事を引き続きご覧ください。今後とも123WORDPRESS.COMをよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Js クラスの構築と継承のケースの詳細な説明
  • JS関数の継承について学ぶ記事
  • JS における ES6 継承と ES5 継承の違い
  • JavaScript の寄生的構成継承についての簡単な説明
  • JavaScript オブジェクト指向クラス継承ケースの説明
  • JavaScript継承のさまざまな方法とメリット・デメリットを詳しく解説

<<:  MYSQL パフォーマンス アナライザー EXPLAIN 使用例分析

>>:  Nexusプライベートサーバー構築原理とチュートリアル分析

推薦する

MySQL可視化ツールNavicatへの接続方法

Navicatをインストールした後次のエラーが発生する場合があります: Client does no...

CentOS8.1 で Gitlab サーバーを構築するための詳細なチュートリアル

Gitlab と Github の違いについては、あまり説明する必要はありません。一言でまとめると、...

HTML で中国語を UTF-8 に変換する方法

HTMLでは、中国語のフレーズ「學好好學」は「學好好學」と表現できます。プロジェクトでは、SMSアラ...

MySQLデータ損失の原因と解決策

目次序文問題の説明原因分析拡大する総括する序文最近、データの欠落やデータの損失に関するフィードバック...

Angularコンポーネントのライフサイクルの詳しい説明(パート2)

目次1. ビューフック1. ngAfterViewInit および ngAfterViewCheck...

MacでDockerがホストマシンにpingできない問題を解決する

解決Docker for Macに付属するLinux仮想マシン(軽量ですが、ソケットファイルを使用し...

jQueryフレームワークは、要素の表示と非表示の3つのアニメーションメソッドを実装しています。

目次1. デフォルトで表示と非表示を切り替える2. スライドして表示と非表示を切り替える3. フェー...

alpineをベースにdockerfileで作成したtomcatイメージの実装

1.アルパインイメージをダウンロードする [root@docker43 ~]# docker pul...

MySQL InnoDB ロックの概要

目次1. 共有ロックと排他ロック2. 意図ロック3. レコードロック4. ギャップロック5. ネクス...

Vueのレスポンシブシステムの原理の詳細な説明

目次Vueのレスポンシブシステムの基本原則1. Object.definePropertyの使い方を...

Element+vueを使用して開始時間と終了時間の制限を実装する

この記事の例では、Element+vueを使用して開始と終了の時間制限を実装するための具体的なコード...

JavaScript における Promise の詳細な説明

目次Promise の基本的な使用法: 1. Promiseオブジェクトを作成する2. プロミス方式...

Weibo の一括フォロー解除機能を実装する JavaScript コード

Weibo ユーザーのフォローを一括で解除するクールな JavaScript コードWeibo には...

UI を通じて Docker を管理する方法

Docker はますます多くのシナリオで使用されています。コマンドラインツールに慣れていない人にとっ...

CentOS 6 および 7 での MySQL 5.7 の詳細なインストール チュートリアル

開発には常にデータが必要です。サーバーとしての Linux では、テスト データを格納するためのデー...