急速にjsの6種類の継承方式を区別します.
4885 ワード
まず、親タイプのアニマルを定義して、次にCat類で父類の継承を実現します.
コア:サブタイプのプロトタイプのオブジェクトは、親タイプのインスタンス(サブクラス.prototype=new親タイプ()と同じです.非常に純粋な継承関係、例としては、サブクラスの例であり、親クラスの例でもある .親類のプロトタイプ方法/プロトタイプの属性が追加され、サブクラスは にアクセスできます.は簡単で、簡単に実現できます.
短所: マルチ継承を実現できないのは、プロタイプが親タイプの例を指しているため、他のタイプのプロトタイプチェーン上の方法を継承できないからです. プロトタイプオブジェクトからの参照属性は、全インスタンス共有 である.サブクラスのインスタンスを作成した場合、親構造関数に を転送できませんでした.
2.構造継承
コア:親の構造関数を使用して、サブクラスの属性と方法を取得します.親クラスの実例的な属性をコピーしたサブクラス(親クラス・コール)と同じです.は、1のサブクラスインスタンスが親タイプ参照属性を共有する問題(プロトタイプではない)を解決した .によってサブクラスのインスタンスが作成された場合、パラメータ を親に渡すことができる.は、複数の親(複数の親)の欠点を達成することができる: の例は親の例ではないが、サブクラスの例 だけである.は、親タイプの例示的な属性と方法だけを継承することができ、プロトタイプの属性/方法 を継承することができません.は関数多重を実現できませんでした.各サブクラスには親のインスタンス関数のコピーがあります.性能に影響を与えます.
3.原型式継承
コア:プロトタイプ継承のobject方法は、本質的にはパラメータオブジェクトに対して浅いコピーです.
4.コピー引継ぎ
コア:サブクラス.prototype.属性=new親類().属性 マルチ相続をサポートします.
短所: 効率が低く、メモリ占有率が高い(親タイプの属性をコピーするため) .は、親類の列挙できない方法を取得できません.プロトタイプの取得が可能です.Object.defineProperty()とsmbol()Object.keys()は、プロトタイプのObject.getOwProtyNamesに手動で設定する必要があります.
5.コンビネーション継承(プロトタイプ、コンストラクタ継承の組み合わせ)
コア:親構造を呼び出すことにより、親の属性を継承し、伝来の利点を保持し、親のインスタンスをサブプロトタイプとすることにより、関数多重化(親クラス・call(this)、サブクラス・プロトタイプ=new親類()を実現します. は、インスタンス属性/方法を継承することができ、プロトタイプ属性/方法(プロトタイプ継承) を継承することもできる.は、サブクラスの例であり、親タイプの例(プロトタイプチェーン) である.引用属性共有問題が存在しない(構造関数継承) アクセス可能 関数多重化(プロトタイプチェーン継承) 短所:は、2回の父親構造関数を呼び出し、2つのインスタンスを生成した(サブクラスの例は、サブタイプのプロトタイプ上のブロック) .
6.寄生グループ引き継ぎ
寄生方式により、親類の例示的な属性を切り落とす.このように、親類の構造を2回呼び出した場合、2回のインスタンス方法/属性を初期化しない.回避される組み合わせ継承の欠点(親類・call(this).var Super=function(){}、Super.prototype=父類.prototype、サブクラス.prototype=new Superパーフェクト 短所:より複雑な を実現します.
追加:ES 6継承
class類extensの父類{constructor}
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.プロトタイプチェーン継承コア:サブタイプのプロトタイプのオブジェクトは、親タイプのインスタンス(サブクラス.prototype=new親タイプ()と同じです.
function Cat(){
}
Cat.prototype = new Animal(); // prototype, ( )
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
利点:短所:
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
利点:3.原型式継承
コア:プロトタイプ継承のobject方法は、本質的にはパラメータオブジェクトに対して浅いコピーです.
function Cat(o){
function F(){}
F.prototype = o;
return new F();
}
let cat = object(person);
cat.name = "Bob";
anotherPerson.friends.push("Rob");
利点:親の方法は、欠点を多重化することができます.親の参照属性は、すべてのサブクラスのインスタンスに共有されます.サブクラスの構築例では、親クラスにパラメータを渡すことができません.ECMAScript 5は、Object.create()を追加することにより、プロトタイプの継承を規範化しました.この方法は2つのパラメータを受信する.1つは新しいオブジェクトのプロトタイプとして使用するオブジェクトと、新しいオブジェクトのために追加の属性を定義するオブジェクトである.一つのパラメータが入った場合、Object.creat()は、Object()方法と同じ挙動を示します.したがって、上記のコードはlet cat=Cat(Animal)=>に変換することができる.let cat=Object.creat(Animal);4.コピー引継ぎ
コア:サブクラス.prototype.属性=new親類().属性
function Cat(name){
var animal = new Animal();
for(var p in animal){
Cat.prototype[p] = animal[p];
}
Cat.prototype.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
利点:短所:
5.コンビネーション継承(プロトタイプ、コンストラクタ継承の組み合わせ)
コア:親構造を呼び出すことにより、親の属性を継承し、伝来の利点を保持し、親のインスタンスをサブプロトタイプとすることにより、関数多重化(親クラス・call(this)、サブクラス・プロトタイプ=new親類()を実現します.
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
Cat.prototype = new Animal();
// 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
利点:6.寄生グループ引き継ぎ
寄生方式により、親類の例示的な属性を切り落とす.このように、親類の構造を2回呼び出した場合、2回のインスタンス方法/属性を初期化しない.回避される組み合わせ継承の欠点(親類・call(this).var Super=function(){}、Super.prototype=父類.prototype、サブクラス.prototype=new Super
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
利点:追加:ES 6継承
class類extensの父類{constructor}
class Cat extends Animal {
constructor(name,food){
// constructor(name)
super(name);
this.food = food
}
eat(food){
//
super.eat(food);
}
}
// 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