継承はオブジェクト指向の考え方の構成要素の 1 つであり、これによりコードの再利用が実現され、コードの量が削減されます。継承には主に親オブジェクトと子オブジェクトの 2 つのディスカッション オブジェクトがあり、子オブジェクトは親オブジェクトのプロパティとメソッドを継承し、子オブジェクトは自分のメソッドと同じように親オブジェクトのプロパティとメソッドを使用できます。プロパティ。オブジェクトの正式な導入を開始する前に、まず親オブジェクトと子オブジェクトのコンストラクターを作成します。
function Parent(name) {
this.name = name;
}
Parent.prototype.work = function () {
console.log(`${
this.name} working...`);
};
function Child(age) {
this.age = age;
}
Child.prototype.eat = function () {
console.log(`${
this.age}eating...`);
};
以下に示すように:
最初の文字が大文字の関数はコンストラクターであり、青色の背景で表され、コンストラクターのプロトタイプ オブジェクトがその上に配置され、緑色の背景で表されます。各コンストラクターのインスタンスはコンストラクターの下に配置され、土色で示されます。
プロトタイプの継承
サブクラスのプロトタイプを親クラスに設定する例:
function Parent(name) {
this.name = name;
}
Parent.prototype.work = function () {
console.log(`${
this.name} working...`);
};
// 原型继承
Child.prototype = new Parent("Tom");
Child.prototype.sleep = function () {
console.log(`${
this.age} sleeping...`);
};
const c = new Child(9);
//c.eat(); // 失去原来的原型对象
c.work(); // 获得父对象方法
c.sleep();
図:
アドバンテージ
シンプルで実装が簡単なため、親クラスの新しいメソッドと属性にサブクラスからアクセスできます。
欠点がある
1) サブクラスにインスタンス属性を追加できます。新しいプロトタイプ属性とメソッドを追加する場合は、新しい親クラスのコンストラクターの後に追加する必要があります。
2) サブクラスのインスタンスを作成する場合、親クラスのコンストラクターにパラメーターを渡すことはできません。
コンストラクターの継承を借用する
継承の借用とは、サブクラスのコンストラクター内で親クラスのコンストラクターを呼び出すことを指します。
function Parent(name) {
this.name = name;
}
Parent.prototype.work = function () {
console.log(`${
this.name} working...`);
};
function Child(name, age) {
Parent.call(this, name); // 借用继承
this.age = age;
}
図:
アドバンテージ
親クラスのプロパティのみを継承する必要がある場合、このメソッドは非常に簡単です。
欠点がある
継承できるのは親クラスのプロパティのみですが、親クラスのメソッドは継承できず、親クラスのプロトタイプ上のプロパティやメソッドも継承できません。
構成の継承
完全な継承は次のようにする必要があります。パブリック メソッドまたはプロパティはプロトタイプ上にあり、固有のものはそれ自体で保存されます。
プロトタイプ継承により、サブクラスが親クラスのプロパティまたはメソッドに確実にアクセスできるようになりますが、親クラスの一部のプロパティは、サブクラスのプロトタイプには保存されますが、独自のインスタンス オブジェクトには保存されません。たとえば、個人が独自の名前を持っている場合などです。プロパティを使用するには、プロトタイプの代わりに name プロパティをインスタンス オブジェクトに追加する必要があります。これは、プロトタイプの継承と借用した継承を組み合わせることによって実現されます。
function Parent(name) {
this.name = name;
}
Parent.prototype.work = function () {
console.log(`${
this.name} working...`);
};
function Child(name, age) {
Parent.call(this, name); // 借用继承
this.age = age;
}
Child.prototype = new Parent("Tom");
Child.prototype.constructor = Child;
Child.prototype.eat = function () {
console.log(`${
this.age}eating...`);
};
const c = new Child("Tom", 12);
図:
アドバンテージ
構成継承は、プロトタイプ チェーンと借用コンストラクターの欠点を回避し、それらの利点を組み合わせます。また、instanceof 演算子と isPrototype() メソッドを使用して、構成継承に基づいて作成されたオブジェクトを識別することもできます。
欠点がある
スーパータイプ コンストラクターは 2 回呼び出されます。1 回はサブタイプ プロトタイプの作成時、もう 1 回はサブタイプ コンストラクター内で呼び出されます。
プロトタイプの継承
既存のオブジェクトに基づいて新しいオブジェクトを作成します。
function createAnother(p) {
function Child() {
};
Child.prototype = p;
return new Child();
}
var p = {
name: "父对象",
say: function () {
},
};
var c = createAnother(p);
console.log(c.name); // "父对象"
図:
ES5 の短縮表現を使用しますObject.create()
。
var c = Object.create(p);
プロトタイプ継承はプロトタイプ継承に非常に似ており、中間オブジェクトにプロトタイプ継承を使用すると、オブジェクトをコピーするように見えますが、実際にはそのプロトタイプが親オブジェクトに変わります。実際には次のようになりますc.__proto__=p
。なぜそれをやらないのでしょうか?
寄生継承
寄生継承は、継承プロセスをカプセル化するためにのみ使用される関数を作成することによって実現されます。この関数は、何らかの方法でオブジェクトを内部的に強化し、最終的にこのオブジェクトを返します。
function createChild(parent) {
const child = Object.create(parent); // 通过 Object.create() 函数创建一个新对象
// 增强这个对象
child.sayGood = function () {
alert("hello world!!!");
};
return child; // 返回这个对象
}
寄生継承は、言葉の厳密な意味での継承とは異なります。
寄生組成の継承
プロパティはコンストラクターを借用することによって継承され、メソッドはプロトタイプ チェーンのハイブリッド形式を通じて継承されます。基本的に、寄生継承は親タイプのプロトタイプを継承し、その結果をサブタイプのプロトタイプに割り当てるために使用されます。
function setPrototypeChain(Child, Parent) {
const c_prototype = Object.create(Parent.prototype);
c_prototype.constructor = Child;
Child.prototype = c_prototype;
}
// 相当于
// Child.prototype.__proto__ = Parent.prototype
図:
ES6クラスの継承
ES6 は継承を実装するために extend と super を使用します。
class Parent {
constructor(name) {
this.name = name;
}
work() {
console.log(`${
this.name} working...`);
}
}
class Child extends Parent {
constructor(name, age) {
super(name);
this.age = age;
}
eat() {
console.log(`${
this.name} at ${
this.age} is eating...`);
}
}
const c = new Child("tom", 12);
c.eat();
c.work();
図:
考察: ES6 で実装された継承メソッドは何ですか?
最後に目を入れます
♥ 私はフロントエンド エンジニアです。あなたの恋人、セン。いいねや注目をしていただきありがとうございます。ディスカッションやコラボレーションへの参加を歓迎します。
★ この記事はオープン ソースであり、CC BY-SA 4.0 プロトコルを使用しています。転載する場合は出典を示してください:フロントエンド エンジニアの自己啓発. GitHub.com@xiayulu。
★ クリエイティブ協力や採用情報については、プライベートメッセージまたはメール:[email protected] に件名を「クリエイティブ協力またはフロントエンドエンジニア募集」と明記してお送りください。
ayulu/FrontEndCultivation)、CC BY-SA 4.0 契約を使用して再印刷する場合は、出典を示してください:フロントエンド エンジニアの自己啓発. GitHub.com@xiayulu.★ クリエイティブ協力や採用情報については、プライベートメッセージまたはメール:[email protected] に件名を「クリエイティブ協力またはフロントエンドエンジニア募集」と明記してお送りください。