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プライベートサーバー構築原理とチュートリアル分析

推薦する

略語マークと頭字語マーク

<abbr>タグと<acronym>タグは、Web ページに表示される略語と...

Angularルーティングアニメーションと高度なアニメーション機能の詳細な説明

目次1. ルーティングアニメーション2. グループクエリとスタガー1. ルーティングアニメーションル...

Vue3 を使用してアップロード コンポーネントを実装するためのサンプル コード

目次一般的なアップロードコンポーネントの開発以下の機能を実装する必要がありますカスタムテンプレートサ...

さまざまなマウスの形状を表現する方法

<a href = "http://" style = "cur...

Linuxのtopコマンド出力の詳細な説明

序文皆さんは Linux で top コマンドを使ったことがあると思います。私は Linux に触れ...

JavaScript 正規表現の説明

目次1. 正規表現の作成2. 使用モード2.1 シンプルモードの使用2.2 特殊文字の使用3. 応用...

jsはシンプルな英語-中国語辞書を実装します

この記事では、参考までに、簡単な英中辞典を実装するためのjsの具体的なコードを紹介します。具体的な内...

MySQLのダウンロードとインストールのプロセスの詳細な説明

1: MySqlをダウンロードする公式サイトのダウンロードアドレス: https://dev.mys...

AngularJSループオブジェクトプロパティで動的列を実装するアイデアの詳細な説明

動的な列を実現するための Angularjs ループ オブジェクト プロパティ利点: オブジェクトを...

Linux で SVN サーバーをインストールする方法

1. Yumのインストール yum でサブバージョンをインストール 2. 構成1. 倉庫を作る/ho...

JavaScript 上級プログラミング: 変数とスコープ

目次1. 元の値と参照値2. インスタンス3. 範囲1. 元の値と参照値6 つの単純なデータ型の値は...

すべてのブラウザに対応したデータURIとMHTMLの完全なソリューション

データURI Data URI は、小さなファイルをドキュメントに直接埋め込むために RFC 239...

リクエスト IP の最後のセグメントに基づいてトラフィックを分割するように Nginx を構成する方法

これは主に、場所パラメータのif判断の設定ジャンプです。迂回により、サーバーの負荷と圧力を軽減できま...

Vue.jsフレームワークはショッピングカート機能を実装します

この記事では、ショッピングカートを実装するためのVue.jsフレームワークの具体的なコードを参考まで...