2019-08-27

1. 組合繼承:又叫偽經典繼承,是指將原型鏈和借用構造函數(shù)技術組合在一塊的一種繼承方式。

下面來看一個例子:

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.sayAge = function() {

? ? alert(this.age);

? }

? var instance1 = new SubType("Nicholas", 29);

? instance1.colors.push("black");

? alert(instance1.colors); //red,blue,green,black

? instance1.sayName(); //Nicholas

? instance1.sayAge(); //29

? var instance2 = new SubType("Greg", 27);

? alert(instance2.colors); //red,blue,green

? instance2.sayName(); //Greg

? instance2.sayAge(); //27

組合繼承避免了原型鏈和借用構造函數(shù)的缺陷,融合它們的優(yōu)點。

2. 原型式繼承

可以在不必預先定義構造函數(shù)的情況下實現(xiàn)繼承,其本質是執(zhí)行對給定對象的淺復制。而復制得到的副本還可以得到進一步的改造。

function object(o) {

? ? function F(){};

? ? F.prototype = o;

? ? return new F;

? }

? var person = {

? name: "Nicholas",

? friends: ["Shelby", "Court", "Van"]

? };

? var antherPerson = object(person);

? antherPerson.name = "Greg";

? antherPerson.friends.push("Rob");

? var antherPerson = object(person);

? antherPerson.name = "Linda";

? antherPerson.friends.push("Barbie");

? alert(person.friends); //Shelby,Court,Van,Rob,Barbie

3. 寄生式繼承

與原型式繼承非常相似,也是基于某個對象或某些信息創(chuàng)建一個對象,然后增強對象,最后返回對象。為了解決組合繼承模式由于多次調用超類型構造函數(shù)而導致的低效率問題,可以將這個模式與組合繼承一起使用。

function object(o) {

? ? function F(){};

? ? F.prototype = o;

? ? return new F;

? }

? function createAnother(original) {

? ? var clone = object(original);

? ? clone.sayHi = function() {

? ? ? alert("Hi");

? ? };

? ? return clone;

? }

? var person = {

? ? name: "Nicholas",

? ? friends: ["Shelby", "Court", "Van"]

? };

? var anotherPerson = createAnother(person);

? anotherPerson.sayHi();

4. 寄生組合式繼承

集寄生式繼承和組合繼承的優(yōu)點與一身,是實現(xiàn)基本類型繼承的最有效方式。

//繼承原型

? function extend(subType, superType) {

? ? function F(){};

? ? F.prototype = superType.prototype;

? ? var clone = new F;

? ? clone.constructor = subType;

? ? subType.prototype = clone;

? }

? //超類方法

? function SuperType(name) {

? ? this.name = name;

? ? this.colors = ["red", "blue", "green"];

? }

? SuperType.prototype.sayName = function() {

? ? return this.name;

? }

? //子類方法

? function SubType(name, age) {

? ? SuperType.call(this, name);

? ? this.age = age;

? }

? //繼承超類的原型

? extend(SubType, SuperType);

? //子類方法

? SubType.prototype.sayAge = function() {

? ? return this.age;

? }

? var instance1 = new SubType("Shelby");

? var instance2 = new SubType("Court", 28);

? instance1.colors.push('black');

? alert(instance1.colors); //red,blue,green,black

? alert(instance2.colors); //red,blue,green

? alert(instance1 instanceof SubType); //true

? alert(instance1 instanceof SuperType); //true

這段例子的高效率體現(xiàn)在它只調用了一次SuperType構造函數(shù),并且因此避免了在SubType.prototype上面創(chuàng)建不必要的多余的屬性。與此同時,原型鏈還能保持不變。因此,還能正常使用instanceof 和 isPrototypeOf()。開發(fā)人員普遍認為寄生組合式繼承是引用類型最理想的繼承范式。

5.多重繼承

繼承一般包括單向繼承和多向繼承,單向繼承模式較為簡單,每個子類有且僅有一個超類,多重繼承是一個比較復雜的繼承模式。一個子類可擁有多個超類。JavaScript原型繼承不支持多重繼承,但可通過混合模式來實現(xiàn)多重繼承。下面讓類C來繼承類A和類B:

function A(x){

? ? this.x = x;?

}?

A.prototype.hi = function(){?

? ? console.log('hi');?

}?

function B(y){?

? ? this.y = y;?

}?

B.prototype.hello = function(){?

? ? console.log('hello');?

}?

// 給Function增加extend方法?

Function.prototype.extend = function(obj) {?

? ? for(var item in obj) {?

? ? ? ? this.constructor.prototype[item] = obj[item];?

? ? }?

}?

// 在類C內部實現(xiàn)繼承?

function C(x,y){?

? ? A.call(this,x);?

? ? B.call(this,y);?

};?

C.extend(new A(1));?

C.extend(new B(2));?

// 通過復制繼承后,C變成了一個對象,不再是構造函數(shù)了,可以直接調用?

C.hi(); // hi?

C.hello(); // hello?

console.log(C.x); // 1?

console.log(C.y); // 2

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容