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

推薦する

Vmvare 仮想マシンを使用して Ubuntu のルート ディレクトリをパーティション分割する方法の紹介

目次序文根拠手順1. CDから仮想マシンを起動する2. GPartedツールを使用してパーティション...

SQLの最適化では間違いがよく起こります。それはMySQLのExplain Planの使い方を理解していないからです。

目次1. 準備2. 説明計画の概要3. フィールドの詳細な説明4. パーティションクエリにはパーティ...

Node.js パッケージ マネージャー npm の具体的な使用方法

目次目的npm init および package.json ファイルモジュールのインストールと管理モ...

MySQLクエリは、フィールドが数値とカンマではないことを指定します。

コアSQL文数字を含まない MySQL クエリ ステートメント: SELECT * FROM tes...

dockerを使用してGrafana+Prometheus構成をデプロイする

docker-compose-monitor.yml バージョン: '2' ネットワ...

MySQLはtruncateコマンドを使用してデータベース内のすべてのテーブルを素早くクリアします

1. まずSELECT文を実行して、すべての切り捨て文を生成します。ステートメント形式: selec...

Reactは無限ループスクロール情報を実装する

この記事では、無限ループスクロールを実現するためのReactの具体的なコードを参考までに紹介します。...

SQL 文で OR と AND を混在させる場合のヒント

現在、このような要件があります。ログインした人がカスタマー サービス担当者である場合、注文は「このカ...

Reactでレシピシステムを実装する方法を解説した記事

目次1. レシピ集1.1 プロジェクトの背景1.2 テクノロジースタック1.3 開発環境1.4. プ...

WIN2008 サーバーのコマンド ラインを使用して IIS7 コンポーネントをインストールおよびアンインストールする方法

注意: .NET FrameWork はコア モードで実行できないため、コア インストール モードの...

MySQLの左結合と内部結合について簡単に説明します

序文最近、X 省のコールド チェーン トレーサビリティ システムの開発で忙しくしています。毎日午後 ...

Reactでwindow.print()を使用した際にページが応答しなくなる問題の解決記録について

目次1. 問題の背景: 2. 問題の原因: 3. 問題解決:要約: 1. 問題の背景: window...

Vueモバイル端末に最適な適応ソリューションについての簡単な説明

序文: 最近の医療モバイル プロジェクトに基づいて、Vue はさまざまな画面のさまざまな画面サイズに...

CSS でデジタル ページング効果のコードと手順を実装する方法

かなりの数のウェブサイトがデジタルページング効果を使用しています。たとえば、このサイトのページングも...

コピー&ペーストはパッケージングの敵です

OO、デザイン パターン、および多くのオブジェクト指向の原則について話す前に、まず 1 つのことを習...