ホームページ  >  記事  >  ウェブフロントエンド  >  (超定番)JavaScriptのオブジェクト継承方法まとめ

(超定番)JavaScriptのオブジェクト継承方法まとめ

不言
不言オリジナル
2018-09-03 10:44:521343ブラウズ

この記事は、JavaScript の (超古典的な) オブジェクト継承メソッドをまとめたものです。必要な方は参考にしていただければ幸いです。

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

キー ポイント: プロトタイプを使用して、ある参照型に別の参照型のプロパティとメソッドを継承させます。コンストラクター、プロトタイプ、インスタンスの関係: 各コンストラクターにはプロトタイプ オブジェクトがあり、プロトタイプ オブジェクトにはコンストラクターへのポインターが含まれ、インスタンスにはプロトタイプ オブジェクトへの内部ポインターが含まれます。

function SuperType(){
  this.property = true;
}
SuperType.prototype.getSuperValue = function(){
  return this.property;
};

function SubType(){
  this.subproperty = false;
}
// 继承自SuperType
SubType.prototype = new SuperType();

SubType.prototype.getSubValue = function (){
  return this.subproperty;
};

var example = new SubType();
alert(example.getSuperValue());//true

プロトタイプを使用してオブジェクトを作成する場合、複数のインスタンスによる参照型の操作が改ざんされるという問題が発生します。この問題は、次のように上記にも存在します。

function SuperType(){
  this.colors = ["red", "blue", "green"];
}
function SubType(){}//即使没有写,也不会影响结果

SubType.prototype = new SuperType();

var example1 = new SubType();
example1.colors.push("black");
alert(example1.colors); //"red,blue,green,black"

var example2 = new SubType(); 
alert(example.colors); //"red,blue,green,black"

2 つのインスタンス オブジェクトの color 属性 example1と example2 が同じポイントを指している場合、1 つのプロパティを変更して、別のインスタンスに影響を与えます。

欠点:
① プロトタイプチェーン継承の複数のインスタンスの参照型属性は同じポイントを指します。1 つのインスタンスがプロトタイプ属性を変更すると、他のインスタンスのプロトタイプ属性も変更されます。
② パラメーターを渡すことができません。
③ 単一継承。

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

キーポイント: .call() と .apply() を使用して、親クラスのコンストラクターを子クラスの関数に導入し、親クラスのコンストラクターを使用して子クラスのインスタンスを拡張します。親クラスをコピーすることと同じです。クラスのインスタンスがサブクラスに与えられます。

function SuperType(name){
  this.name = name;
  this.colors = ["red", "blue", "green"];
}

function SubType(name, age){
  // 继承自SuperType
  SuperType.call(this, name);  
  this.age = age;
}

var example1 = new SubType("Mike", 23);
example1.colors.push("black");
alert(example1.colors);//"red,blue,green,black"

var example2 = new SubType();
alert(example2.colors);//"red,blue,green"

alert(example1.name); // "Mike"
alert(example1.age); // 23

コンストラクター継承の借用の重要な点は、SuperType.call(this, name) が SuperType コンストラクターを呼び出すことです。このようにして、SubType の各インスタンスが SuperType のプロパティをコピーします。

欠点:
①は親クラスのインスタンス属性とメソッドのみを継承でき、プロトタイプの属性/メソッドは継承できません。
②コンストラクターの再利用は実現できず、各サブクラスは親クラスのインスタンス関数のコピーを持ちます。パフォーマンスとコードに影響を与えるため、肥大化します。

3. 組み合わせ継承

キーポイント: プロトタイプチェーン継承コンストラクター継承の2つのモードの利点を組み合わせて、親クラスのコンストラクターを呼び出すことで、親クラスのプロパティを継承し、渡されたプロパティを保持します。次に、親クラスのインスタンスをサブクラスのプロトタイプとして使用することで、関数の再利用が実現されます。

その背後にある考え方は、プロトタイプの属性とメソッドの継承を実現するためにプロトタイプチェーンを使用し、コンストラクターを借用することでインスタンス属性の継承を実現するというものです このように、関数の再利用は、プロトタイプを作成し、各インスタンスに独自の属性があることを確認します。

function SuperType(name){
  this.name = name;
  this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
  alert(this.name);
};

function SubType(name, age){
  //继承属性
  SuperType.call(this, name);
  this.age = age;
}

// 继承方法
SubType.prototype = new SuperType(); 
SubType.prototype.constructor = SubType; 
SubType.prototype.sayAge = function(){
    alert(this.age);
};

var example1 = new SubType("Mike", 23);
example1.colors.push("black");
alert(example1.colors); //"red,blue,green,black"
example1.sayName(); //"Mike";
example1.sayAge(); //23

var example2 = new SubType("Jack", 22);
alert(example2.colors); //"red,blue,green"
example2.sayName(); //"Jack";
example2.sayAge(); //22
欠点:

親クラスのインスタンス プロパティとメソッドは、サブクラスのインスタンスとサブクラスのプロトタイプの両方に存在しますが、メモリを占有するだけです。したがって、サブクラスを使用してインスタンス オブジェクトを作成すると、そのプロトタイプ
同じ属性/メソッドのコピーが 2 つ存在します。 -------このメソッドは、JavaScript で最も一般的に使用される継承パターンです。

4. プロトタイプの継承

キーポイント: オブジェクトを関数でラップし、この関数の呼び出しを返します。この関数は、属性を自由に追加できるインスタンスまたはオブジェクトになります。これは、オブジェクトをコンストラクターのプロトタイプに直接割り当てる object.create() の原理です。

function object(obj){
  function O(){}
  O.prototype = obj;
  return new O();
}
object() は、渡されたオブジェクトの浅いコピーを実行し、O のプロトタイプが渡されたオブジェクトを直接指すようにします。

var person = {
  name: "Mike",
  friends: ["Jack", "Tom", "Joes"]
};

var anotherPerson = object(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Peter");

var yetAnotherPerson = object(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("BoBo");

alert(person.friends);   //"Jack,Tom,Joes,Peter,BoBo"
ECMAScript5 は、新しい Object.create() メソッドを通じてプロトタイプの継承を標準化します。このメソッドは 2 つのパラメーターを受け取ります。新しいオブジェクトのプロトタイプとして使用されるオブジェクトと、追加のプロパティを定義するための新しいオブジェクトとして使用されるオブジェクトです。

var person = {
name:"EvanChen",
friends:["Shelby","Court","Van"];
};
var anotherPerson = Object.create(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");
var yetAnotherPerson = Object.create(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");
console.log(person.friends);//"Shelby","Court","Van","Rob","Barbie"
欠点:

① プロトタイプチェーンによって継承される複数のインスタンスの参照型属性は同じ点を指します (すべてのインスタンスがプロトタイプ上の属性を継承します)。改ざんの可能性があります。
② パラメーターを渡すことができません。そして再利用は実現できません。 (新しいインスタンス属性は後で追加されます)。

5. 寄生継承

キーポイント: 継承プロセスをカプセル化するためだけに関数を作成し、内部的に何らかの方法でオブジェクトを強化し、最終的にコンストラクターを返します。 (プロトタイプの継承の周囲にシェルを配置してそれを返すようなものです)

function createAnother(original){ 
  varclone=object(original); // 过调用函数创建一个新对象
  clone.sayHi = function(){ // 以某种方式增强这个对象
    alert("hi");
  };
  return clone; // 返回对象
}
関数の主な機能は、コンストラクターに属性とメソッドを追加して関数を強化することです。

var person = {
  name: "Nicholas",
  friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi(); //"hi"
デメリット:

① プロトタイプチェーンが継承する複数のインスタンスの参照型属性は同じ点を指しており、改ざんの可能性がある
② パラメータを渡すことができず、プロトタイプは使用されず、再利用できない。 。

6. 寄生結合継承

重要なポイント: コンストラクターを借用して属性を継承し、パラメーターと寄生モードを渡し、プロトタイプ チェーンの混合形式を通じてメソッドを継承し、apply または call Can を使用して関数に別のコンストラクターを導入します。転送される。

function inheritPrototype(subType, superType){
  var prototype = Object.create(superType.prototype); //Object.create创建对象
  prototype.constructor = subType;                    // 增强对象
  subType.prototype = prototype;                      // 指定对象
}

// 父类初始化实例属性和原型属性
function SuperType(name){
  this.name = name;
  this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
  alert(this.name);
};

// 借用构造函数传递增强子类实例属性(支持传参和避免篡改)
function SubType(name, age){
  SuperType.call(this, name);
  this.age = age;
}

// 将父类原型指向子类
inheritPrototype(SubType, SuperType);

// 新增子类原型属性
SubType.prototype.sayAge = function(){
  alert(this.age);
}

var example1 = new SubType("abc", 21);
var example2 = new SubType("def", 22);

example1.colors.push("pink"); // ["red", "blue", "green", "pink"]
example1.colors.push("black"); // ["red", "blue", "green", "black"]
寄生組み合わせ継承は、以前の継承方法の利点を組み合わせ、上記の継承方法のほぼすべての欠点を回避します。これは、最も高い実行効率と最も広い適用範囲を備えています。

短所:

実装プロセスが比較的面倒です。

直接継承できるのに、なぜこのような継承方法を学ぶ必要があるのでしょうか? 主な目的は、彼らのアイデアを学び、より良い基盤を構築することです。これは、将来フレームワークのソース コードを読んだり、コンポーネントやフレームワークを自分でカプセル化する場合に非常に役立ちます。

急いでいたので ES6 拡張機能を追加しませんでした。

関連するおすすめ:

JavaScriptのオブジェクト指向継承メソッド

JavaScript_jsオブジェクト指向で継承を実装する3つの方法

以上が(超定番)JavaScriptのオブジェクト継承方法まとめの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。