JavaScriptで継承を実装する方法は何ですか

青灯夜游
リリース: 2023-01-06 11:17:55
オリジナル
9592 人が閲覧しました

JavaScript が継承を実装する方法: 1. プロトタイプ チェーンの継承; 親クラスのインスタンスをサブクラスのプロトタイプとして使用します。 2. 構造の継承。親クラスのコンストラクターを使用してサブクラスのインスタンスを拡張します。 3. インスタンスの継承。親クラスのインスタンスに新しい機能を追加し、サブクラスのインスタンスとして返します。 4. 継承をコピーします。 5. 組み合わせの継承。 6. 寄生組み合わせの継承。

JavaScriptで継承を実装する方法は何ですか

このチュートリアルの動作環境: Windows7 システム、JavaScript バージョン 1.8.5、Dell G3 コンピューター。

JS はオブジェクト指向の弱い型指定言語であり、継承もその非常に強力な機能の 1 つです。では、JS で継承を実装するにはどうすればよいでしょうか?様子を見ましょう。

JS 継承の実装方法

継承を実装したいので、まず親クラスを用意する必要があります。コードは次のとおりです:

// 定义一个动物类
function Animal (name) {
  // 属性
  this.name = name || 'Animal';
  // 实例方法
  this.sleep = function(){
    console.log(this.name + '正在睡觉!');
  }
}
// 原型方法
Animal.prototype.eat = function(food) {
  console.log(this.name + '正在吃:' + food);
};
ログイン後にコピー

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

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

function Cat(){ 
}
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.eat('fish'));
console.log(cat.sleep());
console.log(cat instanceof Animal); //true 
console.log(cat instanceof Cat); //true
ログイン後にコピー

features:

  • 非常に純粋な継承関係。インスタンスはサブクラスのインスタンスであり、親クラスのインスタンスでもあります。

  • 親クラスは、新しいプロトタイプ メソッド/プロトタイプ属性を追加します。

  • シンプルで実装が簡単

#欠点:

    #サブクラスに属性とメソッドを追加する場合は、関数内で Cat コンストラクターを使用し、Cat インスタンスにインスタンス属性を追加します。プロトタイプのプロパティとメソッドを追加する場合は、new Animal() などのステートメントの後に実行する必要があります。
  • #多重継承は実装できません
  • プロトタイプ オブジェクトのすべてのプロパティはすべてのインスタンスで共有されます
  • サブクラス インスタンスを作成する場合、親クラスのコンストラクターにパラメーターを渡すことはできません
  • 2. 構築の継承

コア:

親クラスのコンストラクターを使用してサブクラスのインスタンスを拡張することは、親クラスのインスタンス属性をサブクラスにコピーすることと同じです (プロトタイプは使用されません)

function Cat(name){
  Animal.call(this);
  this.name = name || 'Tom';
}

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true
ログイン後にコピー
機能:

サブクラスのインスタンスが親クラスの参照属性を共有する 1 の問題を解決しました
  • ##サブクラスのインスタンス作成時に親クラスにパラメータを渡すことができるようになりました

  • 多重継承を実現できます (複数の親クラス オブジェクトを呼び出します)

  • 欠点:

インスタンスは存在しません。親クラスのインスタンス (サブクラスのみ) インスタンス

  • は親クラスのインスタンス プロパティとメソッドのみを継承できますが、プロトタイプのプロパティ/メソッドは継承できません

  • 関数の再利用は実現できません。サブクラスには親クラスのインスタンス関数のコピーがあり、パフォーマンスに影響します

  • 3. インスタンスの継承

コア:

新しい機能を親クラス インスタンスに追加し、サブクラス インスタンスとして返されます。

function Cat(name){
  var instance = new Animal();
  instance.name = name || 'Tom';
  return instance;
}

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // false
ログイン後にコピー

機能:

は、呼び出しメソッドが

であるかどうかを制限しません。 new subclass()
    または
  • サブクラス Class()

    、返されるオブジェクトは同じ効果を持ちます欠点:

インスタンスは親クラスのインスタンスであり、サブクラスではありませんインスタンス

  • は多重継承をサポートしていません

  • 4. 継承をコピーします

    function Cat(name){
      var animal = new Animal();
      for(var p in animal){
        Cat.prototype[p] = animal[p];
      }
      // 如下实现修改了原型对象,会导致单个实例修改name,会影响所有实例的name值
      // Cat.prototype.name = name || 'Tom'; 错误的语句,下一句为正确的实现
      this.name = name || 'Tom';
    }
    
    // Test Code
    var cat = new Cat();
    console.log(cat.name);
    console.log(cat.sleep());
    console.log(cat instanceof Animal); // false
    console.log(cat instanceof Cat); // true
    ログイン後にコピー
  • 特長:

多重継承のサポート

  • 欠点:

#効率が低く、メモリ使用量が多い (親クラスの属性をコピーする必要があるため)

  • 親クラスの列挙不可能なメソッドを取得できません (列挙不可能なメソッドには for in を使用してアクセスできません) )

  • 5 、結合継承

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

function Cat(name){
  Animal.call(this);
  this.name = name || 'Tom';
}
Cat.prototype = new Animal();

// 组合继承也是需要修复构造函数指向的。

Cat.prototype.constructor = Cat;

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // true
ログイン後にコピー

特長:

欠点を補います。インスタンスのプロパティ/メソッドとプロトタイプのプロパティ/メソッドを継承できます

  • これはサブクラスのインスタンスであり、親クラスのインスタンスでもあります

  • ##参照属性の共有は問題ない

  • #パラメータの引き継ぎも可能
  • ##関数の再利用も可能
  • 欠点:
  • #親クラスのコンストラクターは関数を 2 回呼び出され、2 つのインスタンスが生成されます (サブクラスのインスタンスはサブクラス プロトタイプ上のインスタンスをシールドします)

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

  • コア:

    寄生を通じて、親クラスのインスタンス属性を切り離し、親クラスのコンストラクターが 2 回呼び出されたときに、 、インスタンス メソッド/属性は 2 回初期化されず、結合継承の欠点を回避します

    function Cat(name){
      Animal.call(this);
      this.name = name || 'Tom';
    }
    (function(){
      // 创建一个没有实例方法的类
      var Super = function(){};
      Super.prototype = Animal.prototype;
      //将实例作为子类的原型
      Cat.prototype = new Super();
    })();
    
    // Test Code
    var cat = new Cat();
    console.log(cat.name);
    console.log(cat.sleep());
    console.log(cat instanceof Animal); // true
    console.log(cat instanceof Cat); //true
    Cat.prototype.constructor = Cat; // 需要修复下构造函数
    ログイン後にコピー
  • 機能:

完璧な

欠点:

  • 実装がより複雑

付録コード:
  • 例 1 :

    function Animal (name) {
      // 属性
      this.name = name || 'Animal';
      // 实例方法
      this.sleep = function(){
        console.log(this.name + '正在睡觉!');
      }
      //实例引用属性
      this.features = [];
    }
    function Cat(name){
    }
    Cat.prototype = new Animal();
    
    var tom = new Cat('Tom');
    var kissy = new Cat('Kissy');
    
    console.log(tom.name); // "Animal"
    console.log(kissy.name); // "Animal"
    console.log(tom.features); // []
    console.log(kissy.features); // []
    
    tom.name = 'Tom-New Name';
    tom.features.push('eat');
    
    //针对父类实例值类型成员的更改,不影响
    console.log(tom.name); // "Tom-New Name"
    console.log(kissy.name); // "Animal"
    //针对父类实例引用类型成员的更改,会通过影响其他子类实例
    console.log(tom.features); // ['eat']
    console.log(kissy.features); // ['eat']
    ログイン後にコピー
    原因分析:

    キーポイント: 属性検索プロセス tom.features.push を実行するには、まず tom オブジェクトのインスタンス属性を検索します (見つかった)、

    次に、Animal のインスタンスであるプロトタイプ オブジェクト内でそれを探します。存在することがわかった場合は、その値をこのオブジェクトの features 属性に直接挿入します。

    When console.log(kissy.features);上記と同様に、kissy インスタンスで利用できない場合は、プロトタイプで見つけてください。

    プロトタイプに存在する場合は、直接返されますが、このプロトタイプ オブジェクトの features 属性の値が変更されていることに注意してください。

    【関連する推奨事項: JavaScript 学習チュートリアル #]

    以上がJavaScriptで継承を実装する方法は何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
関連するチュートリアル
人気のおすすめ
最新のコース
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート