在JavaScript中實現繼承主要實現如下兩方面的屬性和方法的繼承,這兩方面相互互補,既有共享的屬性和方法,又有特有的屬性和方法。javascript
ES5的繼承方式有多種:主要有原型鏈繼承、借用構造函數、組合式繼承、寄生式繼承和寄生組合式繼承。寄生組合式繼承集
組合式繼承和寄生式繼承的優勢於一身,是ES5中,基於類型繼承的最有效方式。
接下來基於寄生組合式繼承對ES5實現繼承的方面進行解釋。java
//父類 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);//1.借用構造函數:繼承父類的實例屬性; this.age = age; } //2.寄生式繼承:將父類原型的副本強制賦值給子類原型,實現繼承父類的原型方法。 inheritPrototype(SubType, SuperType); SubType.prototype.sayAge = function(){ alert(this.age); }; function inheritPrototype(subType, superType){ var prototype = object(superType.prototype); //建立父類原型的副本 prototype.constructor = subType; //將該副本的constructor屬性指向子類 subType.prototype = prototype; //將子類的原型屬性指向副本 }
以上示例就是ES5中寄生組合式繼承
的一個例子,如何實現子類繼承父類?函數
SuperType.call(this, name);
:當new SubType()
建立子類實例時,首先調用父類構造函數,實現了子類實例繼承父類的實例屬性和方法;inheritPrototype(SubType, SuperType);
:將父類原型副本強制替換成子類原型(1.副本constructor指向子類;2.子類prototype指向副本),使得子類原型包含父類原型中的全部屬性和方法,實現了原型屬性和方法的繼承。ES5中經過函數建立類型並基於原型實現繼承的方式與其餘面向對象的語言相比確實比較另類,沒有那麼簡單明瞭;ES6就提供了更加接近傳統語言的寫法,引入了類的概念。this
class
關鍵字定義類class super{ constructor(name,color){ this.name=name; this.color=["red","blue","green"]; } sayName(){ alert(this.name); } }
1. constructor爲構造函數,若是非顯示建立構造函數,定義類時也會自動建立構造函數; 2. 經過`this`定義的屬性和方法屬於實例屬性和方法;不然都是定義在原型上的屬性和方法; 3. class類中定義的方法`constructor、sayName`都屬於原型方法。
extends
實現類的繼承class Person{ constructor(name,color){ this.name=name; this.color=["red","blue","green"]; } sayName(){ alert(this.name); } } class Student extends Person(){ constructor(name,color,score){ super(name,color);//調用父類構造函數,this指向子類 this.score=score; } showScore(){ alert(this.score); } } let stu1=new Student("xuxu",["white","black","pink"],90); stu1.sayName();//"xuxu" stu1.showScore();//90
1. 子類構造函數中調用父類構造函數,實現了子類繼承父類的實例屬性和方法; 2. 經過extends,子類原型繼承父類原型上的屬性和方法: - Student.__proto__=Person;//做爲對象,子類原型等於父類(構造函數的繼承) - Student.prototype.__proto__=Person.prototype;//做爲構造函數,子類原型對象是父類原型對象的實例。 3. 子類靜態方法繼承父類靜態方法 - 靜態方法的定義:關鍵字static; - 調用方法:類名調用(而不是實例調用); - 普通方法中,super做對象表示父類原型(用來調用父類原型方法); 靜態方法中super做對象表示父類(用來調用父類靜態方法)。 - 普通方法中this指向實例對象;靜態方法中hits指向當前子類。
對象(實例和原型對象)有__proto__屬性,構造函數有prototype屬性,原型對象有constructor屬性。
假設class B extends A
,實例對象分別是insB、insA
:prototype
ES5中:code
ES6中:對象