JavaScript継承のさまざまな方法とメリット・デメリットを詳しく解説

JavaScript継承のさまざまな方法とメリット・デメリットを詳しく解説

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

関数親(){
    this.name = 'ケビン';
}

Parent.prototype.getName = 関数 () {
    コンソールにログ出力します。
}

関数子() {

}

Child.prototype = 新しい Parent();

var child1 = 新しい Child();

console.log(child1.getName()) // ケビン

質問:

1. 参照型のプロパティはすべてのインスタンスで共有されます。例:

関数親(){
    this.names = ['ケビン'、'デイジー'];
}

関数子() {

}

Child.prototype = 新しい Parent();

var child1 = 新しい Child();

child1.names.push('やゆ');

console.log(child1.names); // ["ケビン", "デイジー", "ヤユ"]

var child2 = 新しい Child();

console.log(child2.names); // ["ケビン", "デイジー", "ヤユ"]

2. 子のインスタンスを作成するときに、親にパラメータを渡すことはできません。

2. コンストラクタの借用(古典的な継承)

関数親(){
    this.names = ['ケビン'、'デイジー'];
}

関数子() {
    親.call(これを);
}

var child1 = 新しい Child();

child1.names.push('やゆ');

console.log(child1.names); // ["ケビン", "デイジー", "ヤユ"]

var child2 = 新しい Child();

console.log(child2.names); // ["ケビン", "デイジー"]

アドバンテージ:

  • 1. 参照型のプロパティがすべてのインスタンスで共有されるのを防ぐ
  • 2. 子から親にパラメータを渡すことができる

例えば:

関数 親 (名前) {
    this.name = 名前;
}

関数 子 (名前) {
    Parent.call(これ、名前);
}

var child1 = 新しい Child('kevin');

console.log(child1.name); // ケビン

var child2 = 新しい Child('daisy');

console.log(child2.name); // デイジー

欠点:

  • メソッドはコンストラクターで定義され、インスタンスが作成されるたびにメソッドが再度作成されます。

3. 組み合わせ継承

プロトタイプ継承と従来の継承は連携して動作します。

関数 親 (名前) {
    this.name = 名前;
    this.colors = ['赤', '青', '緑'];
}

Parent.prototype.getName = 関数 () {
    console.log(この名前)
}

関数 子供 (名前, 年齢) {

    Parent.call(これ、名前);

    this.age = 年齢;

}

Child.prototype = 新しい Parent();

var child1 = 新しい Child('kevin', '18');

child1.colors.push('黒');

console.log(child1.name); // ケビン
console.log(child1.age); // 18
console.log(child1.colors); // ["赤", "青", "緑", "黒"]

var child2 = 新しい Child('daisy', '20');

console.log(child2.name); // デイジー
console.log(child2.age); // 20
console.log(child2.colors); // ["赤", "青", "緑"]

利点:プロトタイプ チェーン継承とコンストラクター関数の利点を組み合わせたもので、JavaScript で最も一般的に使用される継承モードです。

4. プロトタイプの継承

関数createObj(o) {
    関数 F(){}
    F.プロトタイプ = o;
    新しいF()を返します。
}


これは、渡されたオブジェクトを作成されたオブジェクトのプロトタイプとして使用するES5 Object.createのシミュレートされた実装です。

デメリット:参照型を含むプロパティ値は、プロトタイプ チェーン継承と同様に、常に対応する値を共有します。

var 人 = {
    名前: 'ケビン'、
    友達: ['デイジー', 'ケリー']
}

var person1 = createObj(person);
var person2 = createObj(person);

person1.name = 'person1';
console.log(person2.name); // ケビン

person1.friends.push('テイラー');
console.log(person2.friends); // ["デイジー", "ケリー", "テイラー"]

注: person1.nameの値が変更されても、 person2.nameの値は変わりません。これは、 person1person2が独立したname値を持っているからではなく、プロトタイプの名前の値を変更するのではなく、 person1.name = 'person1'person1name値を追加するためです。

5. 寄生遺伝

継承プロセスをカプセル化するためだけに使用され、何らかの形でオブジェクトを内部的に拡張し、最終的にオブジェクトを返す関数を作成します。

関数createObj(o){
    var clone = object.create(o);
    clone.sayName = 関数 () {
        コンソールにログ出力します。
    }
    クローンを返します。
}

デメリット:借用コンストラクター パターンと同様に、オブジェクトが作成されるたびにメソッドが作成されます。

6. 寄生的組み合わせ継承

便宜上、結合された継承コードをここで繰り返します。

関数 親 (名前) {
    this.name = 名前;
    this.colors = ['赤', '青', '緑'];
}

Parent.prototype.getName = 関数(){
    console.log(この名前)
}

関数 子供 (名前, 年齢) {
    Parent.call(これ、名前);
    this.age = 年齢;
}

Child.prototype = 新しい Parent();

var child1 = 新しい Child('kevin', '18');

コンソールログ(子1)

複合継承の最大の欠点は、親コンストラクターが 2 回呼び出されることです。

1 回目は、サブタイプ インスタンスのプロトタイプを設定するときです。

Child.prototype = 新しい Parent();

サブタイプのインスタンスを作成するとき:

var child1 = 新しい Child('kevin', '18');

new のシミュレーション実装を思い出してください。実際、この文では以下を実行します。

Parent.call(これ、名前);

ここで、Parent コンストラクターを再度呼び出します。

したがって、この例では、 child1オブジェクトを印刷すると、 Child.prototype colorsというプロパティがあり、その値は['red', 'blue', 'green']。

では、今回はどうすれば卓越性を追求し、重複した電話を避けることができるのでしょうか?

Child.prototype = new Parent()を使用せず、代わりにChild.prototype Parent.prototype間接的にアクセスできるようにしたらどうなるでしょうか?

どのように実装されているかをご覧ください:

関数 親 (名前) {
    this.name = 名前;
    this.colors = ['赤', '青', '緑'];
}

Parent.prototype.getName = 関数 () {
    console.log(この名前)
}

関数 子供 (名前, 年齢) {
    Parent.call(これ、名前);
    this.age = 年齢;
}

// 3 つの重要なステップ var F = function () {};

F.prototype = 親.prototype;

Child.prototype = 新しい F();


var child1 = 新しい Child('kevin', '18');

コンソールにログ出力します。

最後に、この継承メソッドをカプセル化します。

関数オブジェクト(o) {
    関数 F() {}
    F.プロトタイプ = o;
    新しいF()を返します。
}

関数プロトタイプ(子, 親) {
    var プロトタイプ = オブジェクト(parent.prototype);
    プロトタイプ.コンストラクタ = 子;
    child.prototype = プロトタイプ;
}

// 使用する場合:
プロトタイプ(子、親);

「Advanced JavaScript Programming」における寄生的組み合わせ継承の称賛を引用します。

このアプローチの効率性は、 Parentコンストラクターを 1 回だけ呼び出すため、 Parent.prototypeに不要な冗長プロパティが作成されないことです。同時に、プロトタイプ チェーンは変更されないため、 instanceofisPrototypeOf引き続き正常に使用できます。開発者は一般的に、寄生的な構成継承が参照型にとって最も理想的な継承パラダイムであると考えています。

JavaScript の継承のさまざまな方法とそのメリットとデメリットについて詳しく説明しました。JavaScript の継承のさまざまな方法とそのメリットとデメリットの詳細については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Js クラスの構築と継承のケースの詳細な説明
  • JS関数の継承について学ぶ記事
  • JavaScript の継承についてどれくらい知っていますか?
  • JS における ES6 継承と ES5 継承の違い
  • JavaScript の寄生的構成継承についての簡単な説明
  • JavaScript オブジェクト指向クラス継承ケースの説明

<<:  負荷分散と動的および静的分離操作を実現するDocker NginxコンテナとTomcatコンテナ

>>:  MySQLの文字セットと検証ルールの詳細な説明

推薦する

表の境界線の CSS 構文

<br />表の境界線の CSS 構文具体的な内容には、上境界線の幅、右境界線の幅、下境...

CentOS 7 はネットワークカードを変更した後、インターネットにアクセスできません

不明なドメイン名 www.baidu.com を Ping するホストのIPアドレスを変更する右クリ...

Nginxホットデプロイメントの実装

目次セマフォNginx ホットデプロイメント上記のブログ投稿に従ってください。ファイアウォールをオフ...

クリックして展開し、全文を読む機能を実現する純粋なCSS

注記記事表示リストインターフェースを開発する場合、情報の基本的な概要を提供するために記事ヘッダーコン...

Ajax リクエストにおけるクロスドメイン問題の原因と解決策

目次1. クロスドメインはどのように形成されるのでしょうか? 2. クロスドメインの根本的な原因3....

MySQL のマスター スレーブ レプリケーション オプションをオンラインで変更する方法

序文: MySQL で最も一般的に使用されるアーキテクチャは、マスター スレーブ レプリケーションで...

MySQL 5.7.25 圧縮版のインストールと設定方法のグラフィックチュートリアル

この記事では、MySQL 5.7.25圧縮版のインストールと設定方法を参考までに紹介します。具体的な...

CSS 複合セレクタの具体的な使用法

交差点セレクター交差セレクターは、直接接続された 2 つのセレクターで構成されます。最初のセレクター...

VueはTodoListの例をカプセル化し、ブラウザのローカルキャッシュのアプリケーションを実装します。

この記事では主に、Vue で TodoList をカプセル化するケースと、ブラウザのローカル キャッ...

CSS3 で King of Glory マッチング人員読み込みページを実装する方法

King of Glory をプレイしたことがある人なら、このページの効果をよくご存知でしょう。なぜ...

HTML タイトルに二重引用符を追加する方法

<a href="https://www.jb51.net/" title...

HTTPS の有効化に関する経験の共有

国内のネットワーク環境が悪化し続ける中、さまざまな改ざんや乗っ取りが後を絶たず、サイト全体をHTTP...

Linux でファイルプレフィックスを一括で追加する方法

フォルダー内のすべての txt ファイルのファイル名の前に「gt_」を追加する必要があります。つまり...

VSCode と SSH を使用したリモート開発

0. リモート開発が必要な理由組み込み Linux を開発する場合、便宜上、通常は Windows ...

ウェブデザイン:大量の素材の正確な配置と使用

3回の暗記により、大量の資材の正確な場所と目的を記憶でき、その使いやすさが向上します。 これは単なる...