1.シンプルなプロトタイプチェーン
// 创建要继承的父类
function Father() {
// 自带的属性和方法
this.name = "li";
this.show = function() {
console.log("帅");
}
};
// 在父类的原型上添加方法
Father.prototype.callback = function() {
console.log(this.name);
}
// 定义Son
function Son() {
}
// 令Son继承Father
Son.prototype = new Father();// 这句是原型链继承的重点
// 创建Son的对象实例
var son = new Son();
var son1 = new Son();
console.log(son.name); // 可以调用继承于父类上的属性
son.show(); // 可以调用继承于父类上的方法
son1.callback(); // 可以调用father中原型上添加的方法
焦点:
新しいインスタンスのプロトタイプを親クラスのインスタンスと等しくします。
利点:
シンプルで実装が簡単
短所:
- プロトタイプオブジェクトの参照プロパティは、すべてのインスタンスで共有されます。
// 创建要继承的父类
function Father() {
// 自带的属性和方法
this.name = "li";
};
// 定义Son
function Son() {
}
// 令Son继承Father
Son.prototype = new Father(); // 这句是原型链继承的重点
// 创建Son的对象实例
var son = new Son();
var son1 = new Son();
son1.__proto__.name = "zhang"; //通过一个实例改变Son的prototype上的name
// 导致所有实例的name都改变,就叫做引用值共享
console.log(son.name); //"zhang"
console.log(son1.name); //"zhang"
- サブクラスインスタンスを作成するとき、親クラスコンストラクターにパラメーターを渡すことはできません
- 単一継承
2.コンストラクターの継承
// 创建父类
function Father(name) {
this.name = name;
this.arr = [1];
this.show = function() {
console.log("shuai");
}
}
Father.prototype.call = function() {
console.log("call");
};
// 创建子类
function Son(name) {
// 借父类的构造函数来增强子类实例,等于是把父类的实例属性复制了一份给子类实例装上了(完全没有用到原型)
Father.call(this, name); // 核心代码
}
var son1 = new Son("n1");
var son2 = new Son("n2");
son1.arr.push(2); // 向son1的数组中添加一个数
console.log(son1);
console.log(son2);
// 这时son实例的prototype的原型是object
console.log(son1.show === son2.show); // false
焦点:
.call()および.apply()を使用して、親クラスコンストラクターをサブクラス関数に導入します(親クラス関数の自己実行(コピー)はサブクラス関数で実行されます)
利点:
- 親クラスのプロトタイプのプロパティではなく、親クラスのコンストラクターのプロパティのみを継承します
- プロトタイプチェーン継承の欠点を解決する
- 複数のコンストラクターの属性を継承できます(call()を使用)
- 子インスタンスでは、パラメータを親インスタンスに渡すことができます。
短所:
- 親クラスコンストラクターのプロパティのみを継承できます
- コンストラクターの再利用を実現できません(使用するたびに思い出してください)
- 新しい各インスタンスには、肥大化した親クラスコンストラクターのコピーがあります
3.組み合わせ継承(プロトタイプチェーン継承と借用コンストラクター継承の組み合わせ)(一般的に使用)
// 创建父类
function Father(name) {
this.name = name;
this.arr = [1];
this.show = function() {
console.log("shuai");
}
}
Father.prototype.call = function() {
console.log("call");
};
function Son(name) {
Father.call(this, name); // 借用构造函数继承
};
Son.prototype = new Father(); // 原型链继承
var son1 = new Son('li');
var son2 = new Son('zhang');
console.log(son1);
console.log(son2);
焦点:
パラメータ転送と多重化の2つのモードの利点を組み合わせます
利点:
- 親クラスの属性を継承でき、パラメータを渡すことができ、再利用できます
- 新しいインスタンスごとに導入されるコンストラクター属性はprivateです。
短所:
親クラスコンストラクターは2回呼び出され(メモリ消費)、サブクラスコンストラクターがプロトタイプの親クラスコンストラクターに置き換わります。
4.プロトタイプの継承
// 创建父类
function Father(name) {
this.name = name;
this.arr = [1];
this.show = function() {
console.log("shuai");
}
}
Father.prototype.call = function() {
console.log("call");
};
// 生育函数
function beget(obj) {
function F() {
}
F.prototype = obj; //继承了传入的参数
return new F(); //返回函数对象
}
var son1 = new Father(); // 先拿到父类的对象
console.log(son1);
// (核心代码)
var son2 = beget(son1); // 将父类中的属性赋值到每一个子类的函数的原型中
var son3 = beget(son1); // 同上
son2.name = "zhang"; // 修改实例中的属性
console.log(son2);
console.log(son3);
console.log(son2.call); //子类的实例都可以访问父类的原型上的属性和方法
焦点:
オブジェクトを関数でラップしてから、この関数の呼び出しを返します。この関数は、プロパティを自由に追加できるインスタンスまたはオブジェクトになります。(オブジェクトインスタンスが作成されるたびに、新しい関数が返されます)、
利点:
オブジェクトをコピーして、関数でラップします。
短所:
- すべてのインスタンスは、プロトタイプのプロパティを継承します。
- 再利用できません。
V.寄生遺伝
// 创建父类
function Father(name) {
this.name = name;
this.arr = [1];
this.show = function() {
console.log("shuai");
}
}
Father.prototype.call = function() {
console.log("call");
};
function beget(obj) {
function F() {
}
F.prototype = obj; //继承了传入的参数
return new F(); //返回函数对象
}
var son = new Father();
// 将原型式继承的核心代码套一个壳子
function getSubObject(obj) {
var clone = beget(obj); // 核心
return clone;
}
var son1 = getSubObject(new Father());
console.log(son1);
焦点:
プロトタイプの継承にシェルを配置します。
利点:
カスタムタイプは作成されません。オブジェクト(これ)を返すようにシェルを設定するだけなので、この関数は自然に作成された新しいオブジェクトになります。
短所:
プロトタイプは使用されておらず、再利用できません。
6.寄生複合継承(一般的に使用される)
寄生虫:
関数内のオブジェクトを返し、呼び出します
組み合わせ:
1.関数のプロトタイプは別のインスタンスと同じです。
2. applyまたはcallを使用して、パラメーターを渡すことができる別のコンストラクターを関数に導入します
// 创建父类
function Father(name) {
this.name = name;
this.arr = [1];
this.show = function() {
console.log("shuai");
}
}
Father.prototype.call = function() {
console.log("call");
};
function beget(obj) {
function F() {
}
F.prototype = obj; //继承了传入的参数
return new F(); //返回函数对象
}
var bet = beget(Father.prototype);
// 继承了父类函数的原型
function Son() {
Father.call(this);
}
Son.prototype = bet; //继承了get的实例;
bet.constructor = Son; // 修复实例
var son1 = new Son();
// Sub的实例就继承了构造函数的属性,父类实例,
console.log(son1.call);
キーポイント:組み合わせ継承の問題を修正しました